Hashing is not encryption, and it never was
A hash function maps an input of any length onto a fixed-length digest — 32 bytes for SHA-256 — with no key involved and no way back. Encryption has a key and is reversible by design; that is the whole point of it. If someone tells you a password field is "encrypted with SHA-256", they have described two different operations and picked the wrong word for both. Nothing on this page hides your data. It fingerprints it.
The property people actually rely on is that changing one bit of input changes the digest completely and unpredictably, so two files with the same digest are almost certainly the same file. "Almost certainly" is doing real work in that sentence, and how much work depends on which algorithm you picked.
MD5 and SHA-1 are broken, and here is exactly what that means
Both are broken for collision resistance: an attacker can construct two different inputs that produce the same digest. For MD5 this has been practical since 2004 and now takes seconds on a laptop. For SHA-1, the SHAttered attack produced two distinct PDFs with the same SHA-1 digest in 2017, and chosen-prefix collisions followed in 2019, which is the version that actually breaks certificates and signatures.
So, concretely:
| Use | MD5 / SHA-1 | Why |
|---|---|---|
| Digital signatures, certificates, code signing | Do not | An attacker who controls part of the signed content can produce a second document with the same digest and the same valid signature |
| Deduplication where an adversary supplies the files | Do not | Two colliding files collapse into one; a crafted upload can displace or shadow an existing object |
| Git object identity in a hostile repo | Careful | SHA-1 with collision detection is what Git added as mitigation; the underlying function is still SHA-1 |
| Checksum on your own transfer, corruption only | Fine | Random corruption is not a chosen collision. If nobody is trying to fool you, a broken hash still detects a truncated download |
| Matching against a legacy checksum a vendor published | Fine, with eyes open | You are checking transfer integrity, not authenticity. It tells you the bytes arrived intact, not that the vendor's file was not swapped |
The dividing line is whether an adversary controls the input. Collision attacks require crafting both sides; neither MD5 nor SHA-1 is currently broken for preimages, meaning nobody can take a digest you were given and construct a matching file from scratch. That distinction is why "MD5 the ISO to check my download finished" is not a security failure while "MD5 in a signature scheme" is.
CRC32 is not in this conversation because it is not a hash at all. It is a 32-bit error-detecting code designed to catch burst errors in transmission, and you can construct a colliding input by hand. It appears inside ZIP and PNG for exactly that purpose and nothing more.
Fast hashes are the wrong tool for passwords
SHA-256 is fast, and fast is a liability when the input is a password. Commodity GPUs push billions of SHA-256 guesses per second, so a stolen table of SHA-256 password digests is a dictionary attack with an extra step. Salting stops precomputed rainbow tables but does nothing about raw guessing rate.
Password storage uses a deliberately slow, memory-hard family instead: bcrypt, scrypt and Argon2 (Argon2id is the current default recommendation). They take a tunable work factor, generate and store their own salt, and are designed so that hardware acceleration buys the attacker much less than it would against SHA-256. If you are building anything with a login, use the one your platform's library gives you and turn the cost parameter up until it takes something like 100 ms on your server. None of the six digests on this page belongs anywhere near a password column.
When two tools disagree about the same string
Hashes take bytes, not characters, and the disagreement is nearly always about which bytes. This tool encodes text as UTF-8. A tool that used UTF-16 or a legacy code page produces a different digest for the same visible string. Trailing whitespace counts, and a trailing newline is the classic one: echo abc | sha256sum hashes four bytes because echo adds a newline, while the three-character string hashes three. Line endings matter too — a file with CRLF line endings will never match the digest of the same file with LF.
For files there is no encoding ambiguity, so a mismatch there means the bytes genuinely differ: a truncated download, a resumed transfer that went wrong, or a different build than the one the checksum was published for. Check the file size first, since a size mismatch tells you it is truncation and saves you re-reading the whole thing.
One last thing about verifying downloads: a checksum only proves the file matches what the checksum page said. If an attacker can modify the download, they can usually modify the page listing its digest. What raises this from a corruption check to an authenticity check is a signature over the checksum file — a detached GPG signature, or the digest published somewhere structurally separate from the mirror you fetched from.
Questions people ask
Does my file get uploaded?
No. The file is read with the browser File API into memory in the page, hashed there, and discarded when you close the tab. Open the network panel while you compute a digest of a large file and you will see no request. This is also why very large files are limited by your available memory — the whole file is read at once rather than streamed.
Why does the tool implement MD5 by hand?
Because WebCrypto refuses to provide it. The spec deliberately excludes MD5 so that nobody reaches for it in new code, which is the right call, but it leaves you unable to check the MD5 a vendor published in 2011. The implementation here follows RFC 1321 and exists purely to compare against legacy published checksums.
Which digest should I publish for my own release?
SHA-256. It is what package managers, container registries and every current signing tool expect, the output is short enough to paste, and there is no practical attack. Publishing several digests does not make anything safer; a verifier who checks the weakest one you offer gets the weakest guarantee. Publish SHA-256 and sign the file or the checksum list.
How big a file can this handle?
Practically, one to two gigabytes, because the file is read into memory in one piece before hashing. A 100 MB file usually finishes in about a second. Past a couple of gigabytes you will hit a browser memory limit; at that point use sha256sum, certutil -hashfile or Get-FileHash, all of which stream the file.