Hash Comparison
Paste two digests and find out whether they are the same value. Formatting differences are normalised away, and if they differ you are shown exactly which character diverges first.
{{ textCount }}
{{ textError }}
{{ r.value }}
{{ legacyNames }} {{ legacyNames.indexOf(' and ') === -1 ? 'is' : 'are' }} selected. Practical collisions are public for both, so treat the result as a checksum for spotting accidental corruption — not as evidence that a file is authentic.
Drop files here to hash them
Up to 100 files · any size · read in 4 MB chunks, never uploaded
Files are read, not uploaded. Each one is streamed through the hash function in chunks straight from disk, so a multi-gigabyte image never lands in memory and never leaves your device.
{{ f.error }}
{{ r.value }}
The key never leaves this page. It is not sent to a server, not saved to local storage, and not written into the exported files.
{{ hmacError }}
{{ hmacResult }}
HMAC is not a hash with the key glued on the front. It runs the key through the hash
twice with two different pads, which is what makes it resistant to the length-extension
attacks that break a naïve hash(key + message).
Drop the file you want to check
Hashed in your browser · never uploaded
{{ lengthProblem || vError }}
Hash matches
The {{ vResult.label }} digest of {{ vFile.name }} is identical to the hash you supplied, so this is the file that checksum describes. Letter case and surrounding whitespace were ignored.
Both {{ vResult.computed }}
Hash does not match
This file is not the one that checksum describes. Either the download is incomplete or corrupted, or the file has been altered. Downloading it again is the first thing to try.
Computed {{ vResult.cHead }}{{ vResult.cChar }}{{ vResult.cTail }}
Expected {{ vResult.eHead }}{{ vResult.eChar }}{{ vResult.eTail }}
First difference at character {{ vResult.diffAt + 1 }}.
Paste a hash into both boxes to compare them.
Hashes match
Both are the same {{ cmpResult.len }}-character value, so they identify identical content.
Ignored while comparing: letter case, spaces, line breaks, and any
sha256:-style prefix.
Both {{ cmpResult.a }}
Length {{ cmpResult.len }} — consistent with {{ cmpResult.guess }}.
Hashes are different
These are different lengths — {{ cmpResult.a.length }} and {{ cmpResult.b.length }} characters — so they are digests from two different algorithms, and comparing them tells you nothing about the content.
These two digests differ, so they describe different content.
Hash A {{ cmpResult.aHead }}{{ cmpResult.aChar }}{{ cmpResult.aTail }}
Hash B {{ cmpResult.bHead }}{{ cmpResult.bChar }}{{ cmpResult.bTail }}
First difference at character {{ cmpResult.diffAt + 1 }}.
Text, files and secret keys are hashed in your browser. Nothing you enter is ever uploaded to a server.
Comparing two digests
Two 128-character hex strings differing in a single place look identical to the eye. Reading them across as a check is how corrupted downloads get accepted, and it gets harder the longer the digest. This page gives a definite answer and points at the character.
Formatting is normalised, and it says so
A digest copied from a terminal, a release page or a chat message picks up debris: mixed case,
wrapped lines, a leading asterisk from sha256sum output, a
sha256: prefix from a container registry. None of that is part of the value, so it is
removed before comparing — and the tool states what it removed, because a tool that quietly
reformats your input before declaring success is hard to trust when the answer matters.
Different lengths mean different algorithms
If one value is 32 characters and the other is 64 they are an MD5 and a SHA-256, and the same file produces both. Comparing them tells you nothing about the content, so that case is called out specifically rather than reported as a plain mismatch.
Where the difference is matters
Two digests of the same algorithm that differ from the first character are simply different content. A value that matches for most of its length and then diverges is usually a transcription error — a dropped or doubled character while copying — which is worth re-checking before you conclude the file is bad.
See also the Hash Checker.
Frequently asked questions
Why not just look at them?
Because two 128-character hex strings that differ in one place look identical to the eye. Comparing by eye is how corrupted downloads get accepted. This reports a definite answer and points at the character.
What gets normalised before comparing?
Letter case, spaces, tabs, line breaks, a leading asterisk, and a sha256:-style prefix. Each of those is a formatting artefact of how the value was copied, not part of the digest. The tool states what it ignored.
The two hashes are different lengths. What does that mean?
They come from different algorithms, so comparing them tells you nothing about the content. A 32-character value is MD5 and a 64-character one is SHA-256; the same file produces both.
Can I compare a hash to a file?
Use the Hash Checker for that — it hashes the file for you and compares the result. This page is for when you already have two digests.