Hash Generator
MD5, SHA and CRC of text or a whole file. HMAC too, and a checksum to compare against
Digests
matchCollisions can be produced on a laptop in seconds. Fine as a cache key or a file fingerprint, never as evidence that two files are the samematchCollided in public in 2017 and cheaply since. Git still uses it for object names, which is a decision about content addressing, not securitymatchThe default answer. Nothing published comes close to breaking itmatchSHA-512 truncated, with different starting values. Immune to length extension because of the truncationmatchFaster than SHA-256 on 64-bit hardware, slower on 32-bit, and no more secure in any practical sensematchDetects accidental corruption in zip, gzip, PNG and Ethernet. Trivial to forge on purposematchzlib's stream checksum. Faster than CRC-32 and noticeably worse on short inputEvery digest is switched off.
Hex, Base64 or decimal. A sha256sum line or a sha256: prefix is fine as it stands.
A hash takes any amount of input and returns a fixed number of bytes. There is exactly one thing you can do with the result: compare it to another one.
SHA-256("hello") 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-256("Hello") 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
One bit of input changed. Nothing about the output survived it.That is the property everything else rests on. Change one bit anywhere in a four gigabyte file and roughly half the bits of the digest change, with no pattern connecting the two. It is why a digest can stand in for a file, and why comparing digests is a meaningful way of comparing files.
"hello" MD5 5d41402abc4b2a76b9719d911017c592
"hello" SHA-1 aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
"hello" SHA-256 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
"hello" CRC-32 3610a686
"" MD5 d41d8cd98f00b204e9800998ecf8427e
"" SHA-256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Note the last two lines. The empty input has a digest, and it is always the same one. d41d8cd98f00b204e9800998ecf8427e ande3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855are worth recognising on sight: both mean "this hashed nothing", which is almost always a file that failed to load, and not one that was meant to be empty on purpose.
Broken means collisions, not reversal
There is no such thing as decrypting an MD5. The function threw information away and no amount of cleverness puts it back. Every site offering to reverse one is running a lookup table of digests it has already computed, which works beautifully on password123 and not at all on anything with more than about forty bits of entropy in it.
What "broken" means is different and worse: given one input, an attacker can construct a second, different input with the same digest. For MD5 that takes seconds on a laptop. For SHA-1 it was demonstrated publicly in 2017 and has become cheap since. So:
- Fine: a cache key, a shard key, an ETag, a fingerprint for deduplicating files you produced yourself, checking a download against a checksum published by the same party over the same channel.
- Not fine: a signature, a certificate, a commit you are trusting, a content hash where somebody else chose the content, or anything where the answer to "could an attacker have picked this input" is yes.
None of these is a password hash
Every algorithm here is designed to be fast, and modern hardware runs SHA-256 at billions of guesses a second. Storing a password assha256(password), salted or not, means an attacker with your database is running a dictionary through it before you have finished reading the incident report.
Password hashing wants the opposite property: deliberate slowness, tunable upwards as hardware improves, and memory-hardness so that a graphics card is no faster than a CPU. That is bcrypt, scrypt and Argon2, and nothing on this page substitutes for them.
Gluing the key on does not work, and HMAC is the reason why
Not this: SHA-256(secret + message)
Anyone can append to the message and produce
a valid digest for the longer one, without
ever learning the secret.
This: HMAC-SHA-256(secret, message)MD5, SHA-1 and the SHA-2 family are Merkle-Damgård constructions: they process the message in blocks and carry a running state, and the digestis that state. Which means somebody who has a digest can restore the state, carry on hashing, and produce a valid digest forsecret + message + padding + anything they like. They never need the secret.
HMAC hashes twice, with two different pads derived from the key, and that closes it. Turn the key on above and every SHA row becomes an HMAC. MD5 gets one too, worked out by hand on this page, because HMAC-MD5 is still all over old APIs and no browser will touch it.
SHA-384 is the exception in the family: it is SHA-512 with a different starting state and the output cut in half, and because the digest is only part of the internal state there is nothing to continue from.
A checksum answers a different question
CRC-32 and Adler-32 are not on this page as weak hashes. They are not hashes at all. They were designed to notice that a wire flipped a bit, they are cheap enough to run on every Ethernet frame, and anybody who wants a different message with the same value can construct one by hand.
| Where you meet it | Which one |
|---|---|
| zip, gzip | CRC-32 of the uncompressed data, stored in the trailer |
| PNG | CRC-32 over every chunk, so a truncated PNG fails loudly |
| zlib streams | Adler-32, chosen for speed over CRC-32 |
| Ethernet | CRC-32, in hardware, on every frame |
If a tool tells you a CRC matched, it means the file arrived intact. It does not mean the file is the one you asked for.
The same digest, twice, looking nothing alike
SHA-256("hello")
hex 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Base64 LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
The same 32 bytes. Two strings with nothing in common to look at.A surprising share of "the checksums do not match" is one side printing hex and the other printing Base64. Docker digests are hex with ansha256: prefix. Subresource integrity attributes are Base64 with an sha256- prefix. Both refer to the same 32 bytes.
The comparison box above takes any of them: hex in either case, with or without colons or spaces, Base64 with or without padding, asha256sum line with the filename still attached, or a decimal CRC. If it matches something, the row says so. If it matches nothing, the length alone narrows down what produced it.
Digest lengths, and what they rule out
| Hex characters | Bits | What it could be |
|---|---|---|
| 8 | 32 | CRC-32, Adler-32 |
| 32 | 128 | MD5, MD4, a UUID with the hyphens taken out |
| 40 | 160 | SHA-1, RIPEMD-160, a git object id |
| 56 | 224 | SHA-224, SHA3-224 |
| 64 | 256 | SHA-256, SHA3-256, BLAKE2s |
| 96 | 384 | SHA-384, SHA3-384 |
| 128 | 512 | SHA-512, SHA3-512, Whirlpool, BLAKE2b |
Length narrows it down and never settles it. SHA-256 and SHA3-256 are different functions producing different values at the same length, and the only way to tell which one you are holding is to compute both.
Comparing two digests is not ===
In a browser, checking a digest with a normal string comparison is fine. On a server checking a signature, it is not: string comparison stops at the first byte that differs, so the time it takes leaks how much of the value was correct, and an attacker with enough attempts recovers the digest one byte at a time.
Every language has a constant-time comparison for this:crypto.timingSafeEqual in Node, hmac.compare_digestin Python, subtle.ConstantTimeCompare in Go. Use it anywhere the value being compared is a secret.