SHA-256 on the command line

printf '%s' 'hello' | sha256sum

printf '%s' 'hello' | sha256sum prints the SHA-256 of hello on Linux. On macOS, use shasum -a 256, which gives the same digest:

printf '%s' 'hello' | sha256sum
# 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  -
printf '%s' 'hello' | shasum -a 256
# 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  -

The - stands for standard input; with a file it’s the file name. macOS 27 also has a BSD sha256sum in /sbin that prints the same line. The tool below hashes hello to the same digest and, given that digest to compare, marks its SHA-256 row as the match.

The echo trap

echo hello | sha256sum
# 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03  -

echo adds a newline, so this is the hash of 6 bytes, hello\n, and it shares nothing with 2cf24dba…. Paste it into the tool’s Compare with a hash box and no row matches until you press Enter after hello. printf '%s' writes the text exactly. Don’t count on echo -n: under macOS’s /bin/sh it prints -n hello and a newline, so echo -n hello | shasum -a 256 gives 1428360b4af98bce66b16e40727110404148c47890a27e4a7e5972a2850686fa.

Plain shasum without -a 256 is SHA-1: for a file holding hello it prints aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d, 40 hex characters, not 64.

Verify a download

Checksum files list one <digest> <file name> per line. -c reads such a file, hashes each file it names and reports:

printf '%s' 'hello' > hello.txt; echo hello > hello-nl.txt
sha256sum hello.txt hello-nl.txt > SHA256SUMS
sha256sum -c SHA256SUMS
# hello.txt: OK
# hello-nl.txt: OK

Change hello.txt and its line fails, with exit status 1:

sha256sum -c SHA256SUMS
# hello.txt: FAILED
# hello-nl.txt: OK
# sha256sum: WARNING: 1 computed checksum did NOT match

shasum -a 256 -c SHA256SUMS does the same on macOS. A project’s checksum file usually lists every release; --ignore-missing skips the ones you didn’t download instead of reporting them as failures.

To check one file against a digest from a web page, pipe the line in, with two spaces between digest and name:

echo "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  hello.txt" | sha256sum -c
# hello.txt: OK

GNU sha256sum also accepts one space, but shasum doesn’t: shasum: standard input: no properly formatted SHA checksum lines found.

Elsewhere

  • OpenSSL, anywhere it’s installed: openssl dgst -sha256 hello.txt. OpenSSL 3 prints SHA2-256(hello.txt)= 2cf24dba…; the LibreSSL that macOS ships prints SHA256(hello.txt)= 2cf24dba….
  • PowerShell on Windows: Get-FileHash hello.txt uses SHA-256 by default and prints the digest in uppercase, which is the same hash.

Try it in the Hash Generator

Nothing leaves your browser: every digest is worked out here, in the page.

Case and spaces are ignored, so a hash from a checksum file goes straight in.

The input’s SHA-256 digest, character for character.

Hashing the 5 bytes of UTF-8 text.

AlgorithmDigestCopy
MD5 · 128 bits · broken5d41402abc4b2a76b9719d911017c592
SHA-1 · 160 bits · brokenaaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
SHA-256 · 256 bits2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-384 · 384 bits59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f
SHA-512 · 512 bits9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043

MD5 and SHA-1 are broken: collisions can be built on purpose, so a digest that matches proves nothing about who wrote a file. Use SHA-256 to check a file you downloaded. For passwords, use neither: bcrypt or Argon2 is slow on purpose and salts every hash, so a stolen list can’t be cracked in bulk.

Runs in your browser. Nothing you enter is sent anywhere.