How a release team checks a download, and where the browser leaves you stranded
Every serious project publishes two things: the artifact, and a small text file sitting beside it. Ubuntu ships SHA256SUMS next to every ISO. Apache attaches a .sha512 to each release. The Linux kernel archive posts sha256sums.asc. That second file holds one line per artifact, and the line is dull on purpose: a digest, two spaces, a file name.
On a Linux box the check is one command. You put the manifest next to the downloads, run sha256sum -c SHA256SUMS, and the shell prints OK or FAILED beside each name. On Windows you get certutil -hashfile, which handles exactly one file and prints no verdict at all, so you end up comparing 64 characters by eye. On a locked down work laptop you often get neither.
That gap is what this page fills.
The verify mode reads the same manifest formats the command line tools write. Plain digest filename lines from sha256sum and md5sum, the BSD tagged layout SHA256 (file) = digest that the FreeBSD and macOS tools emit, comment lines starting with a hash mark, and the asterisk that GNU tools prepend to a name when the file was read in binary mode. The algorithm comes from the length of the digest on each line, so a manifest mixing SHA-256 and SHA-512 entries verifies correctly without you selecting anything.
A matching digest proves the bytes you hold are the bytes the manifest describes. It says nothing about who wrote the manifest. If the SUMS file came down the same connection, from the same server, as the download itself, then anyone able to swap one was able to swap the other.
Our recommendation: treat an unsigned manifest served alongside the artifact as a corruption check, full stop. Real tamper detection needs the manifest signed with a key you already trust, which is why distributions publish a detached GPG signature over the SUMS file rather than over each ISO.
What runs when you drop a file in
The browser never hands over a file's contents when you pick it. You get a handle: name, size, MIME type, last modified stamp. Reading is a separate, explicit act, and this page reads in pieces.
- A slice is requested through
Blob.slice, 8 MB at a time, which pulls that range off disk and nothing more. - The slice feeds a running hash state. MD5, SHA-1 and SHA-256 chew through it in 64 byte blocks, keeping four to eight 32 bit registers between calls. CRC-32 walks a 256 entry lookup table byte by byte.
- The slice is released and the next one requested. Peak memory stays near 8 MB whether the file is 3 MB or 30 GB.
- After the last byte, the state is padded to a block boundary, the total bit length is appended, one final block runs, and the registers are printed as hexadecimal.
No network request happens anywhere in that path. Pull your ethernet cable out and the page behaves identically, which is worth knowing for the files people most want to fingerprint: disk images, database dumps, backup archives, anything that has no business leaving the machine for a fingerprint.
SHA-512 is the one exception, and the reason is a gap in the web platform rather than a design choice here. WebCrypto exposes crypto.subtle.digest, which is fast and native, but it takes the whole input in one call. There is no incremental interface. So SHA-512 loads the file into memory in full before hashing. Keep it under roughly 500 MB, or pick one of the streaming algorithms for anything larger. The tab will run out of memory rather than give you a wrong answer, but a crash halfway through a 4 GB ISO is still a wasted five minutes.
Picking an algorithm when the manifest does not pick for you
In verify mode this question never comes up, since the manifest decides. In hash mode you are producing the manifest, so the choice is yours and it matters more than most people assume.
| Algorithm | Hex length | Where you meet it | Our read on it |
|---|---|---|---|
| CRC-32 | 8 | ZIP entries, PNG chunks, Ethernet frames, firmware images | Error detection, not identity. Random collisions appear once you have roughly 65,000 files, so never use it as a dedup key. |
| MD5 | 32 | Older mirrors, asset pipelines, legacy databases you inherited | Reliable against a bad cable and useless against a person. Collisions run in seconds on a laptop. |
| SHA-1 | 40 | Git object IDs, older certificate chains, some vendor tooling | Broken for collisions since the 2017 SHAttered PDFs. Keep it for compatibility with systems you have no ability to change. |
| SHA-256 | 64 | The default for release manifests, container digests, code signing | The one to write when the choice is open. No practical attack, and every platform reads it. |
| SHA-512 | 128 | Debian and Apache releases, password hashing schemes, older FIPS work | Faster than SHA-256 in native 64 bit code, and memory hungry here. Pick it to match a manifest, not for extra safety. |
Longer is not safer past SHA-256 for this task. A 256 bit digest already puts a deliberate collision far outside anything buildable, and the extra 64 characters mostly make manual comparison harder.
One algorithm runs per batch in hash mode. That looks like a limitation and it is a deliberate one: a SUMS file holds a single algorithm, so exporting a valid manifest means committing to one. When you want five digests over the same input side by side, the Hash Generator Suite is built for that shape of question instead.
Four ways a verification goes wrong quietly
A loud failure is fine. You see FAILED, you download again. The bad ones are the checks that look like they passed, or that failed for a reason having nothing to do with the file.
- Comparing against the wrong algorithmYou hash with SHA-256, the project published SHA-512, and the two strings differ everywhere. That reads like a corrupt download and is nothing of the sort. Count the characters first: 32 is MD5, 40 is SHA-1, 64 is SHA-256, 128 is SHA-512. Verify mode does this counting for you and labels each row with the algorithm it detected.
- Hashing a text file your editor rewroteOpen a file, save it, and a Windows editor may convert every line ending from LF to CRLF. One extra byte per line changes the digest completely. A UTF-8 byte order mark does the same thing at the front of the file. When a text file fails verification and a binary from the same archive passes, line endings are the first suspect, and a byte-level file comparison will show you the drift.
- Trusting a manifest from the page you downloaded fromCovered above and worth repeating, since it is the mistake with the largest gap between how safe it feels and how much it protects.
- Path mismatches between manifest and diskA manifest written from a build directory holds
dist/app.tar.gzwhile your download folder holdsapp.tar.gz. Strict tools call that a missing file. This page strips the folder portion and matches on the base name, falling back to a case insensitive match for manifests written on Windows. That is friendlier, and it also means two files with the same name in different folders will collide in the list.
What this page will not do
- Not hereFolder recursion. A browser hands over only what a person selected, so hashing a directory tree belongs in a shell loop. The Directory Tree Generator covers the listing half of that job.
- Not hereBLAKE3 and SHA-3. An earlier version of this page listed both and returned random hexadecimal for them, which is worse than offering nothing. Doing them properly needs a WASM build weighing more than the rest of the page, so they stay out until that trade looks worth it.
- Not hereSignature checking. Verifying the GPG signature over a SUMS file needs a keyring and a trust decision, neither of which belongs in a browser tab.
- Not hereReverse lookup. A digest is one way. There is no table behind this page and no route from 64 characters back to a file.
- Works wellBatches of a few hundred small files, or a handful of multi gigabyte images on a desktop browser. Mobile is the real ceiling, since phone browsers evict background tabs and a long hash often dies partway.
For the narrower job of fingerprinting one file against one published checksum, the Checksum Validator is a shorter path. This page earns its keep when the count goes above one.
