346

I know the string "foobar" generates the SHA-256 hash c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 using http://hash.online-convert.com/sha256-generator

However the command line shell:

hendry@x201 ~$ echo foobar | sha256sum
aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f  -

Generates a different hash. What am I missing?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hendry
  • 9,725
  • 18
  • 81
  • 139
  • 6
    `sha256sum < foobar`. No need for [cat](http://pubs.opengroup.org/onlinepubs/000095399/utilities/cat.html), [echo](http://pubs.opengroup.org/onlinepubs/000095399/utilities/echo.html), [printf](http://pubs.opengroup.org/onlinepubs/000095399/utilities/printf.html), ... See also [Useless use of cat?](http://stackoverflow.com/q/11710552/873282) – koppor Dec 17 '16 at 20:10
  • 14
    @koppor `< foobar` is not the same as `echo foobar |`. The equivalent for `echo foobar |` would be `sha256sum <<< foobar` but that does add a newline to foobar just like `echo`. – mvds Feb 16 '17 at 15:07
  • 1
    Does not work, it claims `foobar: No such file or directory`. – kap Apr 04 '22 at 11:33

8 Answers8

533

echo will normally output a newline, which is suppressed with -n. Try this:

echo -n foobar | sha256sum
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
mvds
  • 45,755
  • 8
  • 102
  • 111
129

If you have installed openssl, you can use:

echo -n "foobar" | openssl dgst -sha256

For other algorithms you can replace -sha256 with -md4, -md5, -ripemd160, -sha, -sha1, -sha224, -sha384, -sha512 or -whirlpool.

Farahmand
  • 2,731
  • 1
  • 24
  • 27
  • Is there a way to specify the number of rounds you want in sha512? I looked and could not find it and wondered if you would know? – f1lt3r Jun 08 '17 at 23:57
  • 2
    @AlistairMacDonald - I don't know exactly what you are looking for. AFAIK, SHA512 needs 80 rounds; If you want to manipulate the function, it won't be sha512 anymore. BTW, you can search / ask your question in [crypto.stackexchange.com](https://crypto.stackexchange.com/ "Cryptography Stack Exchange"). – Farahmand Jun 09 '17 at 12:27
54

If the command sha256sum is not available (on Mac OS X v10.9 (Mavericks) for example), you can use:

echo -n "foobar" | shasum -a 256

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sucrenoir
  • 2,994
  • 1
  • 27
  • 31
  • 2
    Nice! I've added this to my .bash_profile function sha256() { echo -n "$*" | shasum -a 256 } and call like: ~$ sha256 foobar – rbento Feb 15 '17 at 05:52
  • 2
    Or do you mean *[Ubuntu 10.10 (Maverick Meerkat)](https://en.wikipedia.org/wiki/Ubuntu_version_history#Ubuntu_10.10_.28Maverick_Meerkat.29)*? (no 's', *Maverick*). It was released in 2010 whereas Mac OS X v10.9 was released one month before this answer. – Peter Mortensen Jun 01 '20 at 14:32
36

echo -n works and is unlikely to ever disappear due to massive historical usage, however per recent versions of the POSIX standard, new conforming applications are "encouraged to use printf".

Nicholas Knight
  • 15,774
  • 5
  • 45
  • 57
16

For the sha256 hash in base64, use:

echo -n foo | openssl dgst -binary -sha256 | openssl base64

Example

echo -n foo | openssl dgst -binary -sha256 | openssl base64
C+7Hteo/D9vJXQ3UfzxbwnXaijM=
stevec
  • 41,291
  • 27
  • 223
  • 311
  • 2
    I'm glad I scrolled down - had been trying to get a base64 hash by combining `shasum` and `base64` and kept getting the wrong result. The key is the `-binary` arg passed to `openssl`, thanks for posting! – Paul Apr 09 '22 at 06:37
  • make sure you filter the output before pipng it into another type. In linux we get stdin= and some give a - at the end. always cut that out using | cut -d " " -f2 . Depending on where you want to cut you may need -f1 – nassim Jan 15 '23 at 17:00
13

echo produces a trailing newline character which is hashed too. Try:

/bin/echo -n foobar | sha256sum 
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nordic Mainframe
  • 28,058
  • 10
  • 66
  • 83
13

Use printf instead of echo to avoid adding an extra newline.

printf foobar | sha256sum

For an arbitrary string, the %s format specifier should be used.

printf '%s' 'somestring' | sha256sum
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
9

I believe that echo outputs a trailing newline. Try using -n as a parameter to echo to skip the newline.

Thomas Owens
  • 114,398
  • 98
  • 311
  • 431