The MD5 hash value is different from Bash and PHP

60

4

I tried to generate the MD5 sum (using md5sum) of a string, "hello". I tried out different methods as the md5sum tool in Linux, PHP's MD5() function as well as various online text to md5sum translators.

echo "hello" | md5sum

and

echo "hello" > file && md5sum file

Gave the result b1946ac92492d2347c6235b4d2611184. However, PHP's md5() function and almost all online generators gave the output 5D41402ABC4B2A76B9719D911017C592.

What is the reason?

Himanshu Shekhar

Posted 2016-02-21T16:42:03.033

Reputation: 780

Question was closed 2016-02-25T22:43:08.827

38echo -n "hello" – Martin York – 2016-02-21T21:27:53.457

Answers

80

By default, echo includes a newline character at the end of the output. However, PHP and the online sites you used do not include the newline. To suppress the newline character, use the -n flag:

echo -n "hello" | md5sum

Output:

5d41402abc4b2a76b9719d911017c592  -

See: help echo


or with printf:

printf "%s" "hello" | md5sum

Cyrus

Posted 2016-02-21T16:42:03.033

Reputation: 4 356

I would suggest showing the more widely compatible form before the one that relies on behavior unspecified by POSIX. – Charles Duffy – 2016-02-22T22:36:46.927

Thank you. I prefer to show the problem first with his own example and the behavior of echo. – Cyrus – 2016-02-22T22:53:09.100

7Unless you know the OP's operating system, you don't know that the modified version of "their own example" will actually work. echo -n could echo -n if their Linux is using a stripped-down Busybox. – Charles Duffy – 2016-02-22T22:54:36.183

I know OP's operating system. – Cyrus – 2016-02-22T22:55:32.080

They specify their kernel, but where do they say more than that? – Charles Duffy – 2016-02-22T22:55:57.347

@CharlesDuffy: Good catch. – Cyrus – 2016-02-22T22:56:56.760

what about the extra - at the end? – lrkwz – 2017-05-12T10:08:30.977

@lrkwz: I assume that means the data came from stdin and not from a file.

– Cyrus – 2017-05-12T19:21:57.197

100

@Cyrus's answer is exactly on point with how to resolve this - to explain, when using echo it will output a newline at the end of the string. As you can see on this online output, hello with a newline outputs exactly the MD5 you were getting previously. Using -n suppresses the newline, and will then give you the result you expected.

enter image description here

Edit:

You can see it clearly if you output it to hexdump, which shows the hexadecimal of the bytes there.

$ echo "str_example" | hd
00000000  73 74 72 5f 65 78 61 6d  70 6c 65 0a              |str_example.|

See the 0a (\n) in the end of the string

$ echo -n "str_example" | hd
00000000  73 74 72 5f 65 78 61 6d  70 6c 65                 |str_example|

With -n echo doesn't put a new line (\n) in the end

Now with a empty string

$ echo  "" | hd
00000000  0a                                                |.|

Just the New Line character

$ echo -n  "" | hd

Empty string, so hexdump shows no output

Jonno

Posted 2016-02-21T16:42:03.033

Reputation: 18 756

2Would be more interesting to pipe echo hello and echo -n hello to hexdump -C respectively ;) – Tom Yan – 2016-02-21T21:00:01.897

19

I recommend against echo -n, since it's nonstandard and inconsistently supported (see the Single Unix Spec for echo and a more detailed catalog of incompatibilities by Sven Mascheck). In you want it to work consistently, use printf instead; it's a bit more complex to use (you have to specify a format string in addition to the data you want printed), but IMO worth it to avoid trouble. In this case, printf "%s" "hello" will do the trick.

– Gordon Davisson – 2016-02-22T06:33:52.150