A common situation: a release page lists a SHA-256 next to the download, and you want to check the file before you run it, on a machine where you would rather not open a terminal. This guide explains what the check proves, how the browser computes the hash without uploading the file, and what to do when the values do not match.
Why a Checksum Even Matters
A cryptographic hash takes any byte stream and produces a short, fixed-length fingerprint. Two properties make hashes useful for downloads:
- Determinism — the same bytes always produce the same hash.
- Avalanche — changing a single bit anywhere in the input changes the whole output.
So a download that was cut short, damaged on a mirror, or changed by a proxy gives a different SHA-256. Comparing the publisher’s value with the one computed on your machine catches all of these without downloading again.
It is not, by itself, proof of authenticity — that needs a signature on the checksum list. But “the file I got matches the file the publisher listed” is the precondition for everything else.
SHA-256 vs the Legacy Algorithms
ZeroTool’s File Hash Checker computes six algorithms. They are not interchangeable:
| Algorithm | Output | Collision resistance | Where you meet it |
|---|---|---|---|
| CRC32 | 32 bits | None (error check only) | SFV files, the CRC-32 field of every ZIP entry (APPNOTE) |
| MD5 | 128 bits | Broken (2004) | Older download pages |
| SHA-1 | 160 bits | Broken (2017, SHAttered) | Older download pages, Git object IDs |
| SHA-256 | 256 bits | Strong | Node.js SHASUMS256.txt, Ubuntu SHA256SUMS |
| SHA-384 | 384 bits | Strong | Subresource Integrity examples in the W3C SRI spec |
| SHA-512 | 512 bits | Strong | Firefox SHA512SUMS, npm integrity values |
“Broken” for MD5 and SHA-1 means an attacker can craft two different files with the same hash. A matching MD5 still tells you the download was not damaged by accident; it no longer tells you nobody changed it on purpose. That is why the tool tags MD5 and SHA-1 as legacy.
If you set a policy, pin SHA-256. If a vendor only publishes MD5, compute it, treat the result as a transfer check, and ask for SHA-256.
How the Browser Computes the Hash
The browser’s built-in crypto.subtle.digest() takes the whole input in one buffer; it has no way to feed a file in pieces. An earlier version of the tool did exactly that and read the file into memory with File.arrayBuffer(): a 1 GB file added about 2 GB to the tab, and a 3 GB file failed.
The current tool streams instead. Each selected algorithm runs in its own Web Worker, reads the file with file.stream() in 1 MB pieces and feeds them to hash-wasm, which keeps the hash state between pieces. Memory stays near one piece per worker. On 2026-10-01, in desktop Chromium on an Apple M1 Max, SHA-256 of a 1 GB file took 4.3 seconds and the tab used about 100 MB more memory; the 4,080,486,400-byte Ubuntu 24.04.5 server ISO matched its official value.
There is no upload step and nothing is stored: the only network request is for the hashing script itself. The same streaming idea in a few lines:
import { createSHA256 } from 'hash-wasm';
async function sha256(file) {
const hasher = await createSHA256();
hasher.init();
const reader = file.stream().getReader();
for (;;) {
const { done, value } = await reader.read();
if (done) break;
hasher.update(value);
}
return hasher.digest('hex');
}
For new Blob(['abc']) this returns ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad, the FIPS 180-2 test value.
The same result from a shell:
# Linux (GNU coreutils)
sha256sum node-v24.21.0-darwin-arm64.tar.gz
# macOS
shasum -a 256 node-v24.21.0-darwin-arm64.tar.gz
# Windows
certutil -hashfile node-v24.21.0-darwin-arm64.tar.gz SHA256
Get-FileHash node-v24.21.0-darwin-arm64.tar.gz
The output formats differ: sha256sum and shasum print the hash and the file name, certutil prints a header line, the hash and a completion line, and Get-FileHash prints a table with upper-case hex. The tool’s compare box reads all of these, plus SHA256SUMS files, BSD-style SHA256 (file) = … lines and Base64 / SRI values, and compares exact values.
A Worked Example: Checking a Node.js Download
Node.js publishes SHASUMS256.txt in each release folder. For v24.21.0 it has 34 lines; line 3 is:
bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057 node-v24.21.0-darwin-arm64.tar.gz
Download the tarball (52,909,993 bytes), drop it on File Hash Checker, and paste all 34 lines into the compare box. SHA-256 starts on its own, and the file card reads “Matches the SHA-256 listed for node-v24.21.0-darwin-arm64.tar.gz (line 3).” The other 33 lines are counted as files you did not select, the same as sha256sum -c --ignore-missing.
If a download stopped early — say only the first 30,000,000 bytes arrived — the card turns red: “Does not match the SHA-256 listed for node-v24.21.0-darwin-arm64.tar.gz (line 3). First difference at character 1.” Then:
- Check that you copied the whole 64-character value and the right line. A missing or extra character is reported as a length or character error, not as a mismatch.
- Download again, from another mirror if possible; transfer damage is the usual cause.
- If the project signs its checksum list, verify the signature before trusting any value in it. Node.js explains this under Verifying binaries (
SHASUMS256.txt.asc); Ubuntu publishesSHA256SUMS.gpgand a verification tutorial. A correct hash from a tampered list proves nothing.
The tool stops at hashing. Signature checks need the publisher’s OpenPGP key, and gpg --verify on your own machine is the right place for them.
Edge Cases the Tool Won’t Solve For You
- Very large files take time. There is no fixed size limit, but time grows with size and the tab must stay open until the hash finishes.
- A folder has no single hash. You can drop a folder and the tool hashes every file in it (up to 1,000), keeping each relative path so a
SHA256SUMSlist matches by name. A fingerprint of the folder as a whole needs an archive: hash the.tar.gzor.zipinstead. - Hashing while downloading. The tool reads a file that is already on disk. Hashing the stream as it arrives is a command-line job (
curl … | sha256sum). - Other algorithms and problems. SHA-224, SHA3, BLAKE2 and BLAKE3 are not computed; such values are reported as unsupported. For keyed integrity use the HMAC Generator, for password storage the Bcrypt Generator, and for text rather than files the Hash Generator.
Why a Standalone Tool Helps
A developer who lives in a terminal will reach for sha256sum. Many downloads happen elsewhere: on Windows, on a locked-down machine, or while helping a colleague. The browser tool covers those cases:
- It is the same page on macOS, Windows, Linux and ChromeOS.
- It needs no installation or admin rights.
- It works on files already on disk and accepts drag and drop of files and folders.
- It compares against a pasted value or a whole checksum list, by file name, instead of asking you to compare 64 characters by eye.
What it is not: a signature verifier, or a replacement for integrity checks in CI.
Further Reading
- File Hash Checker — the tool, with more examples and a comparison with other in-browser checkers.
- GNU coreutils: cksum output modes — the
sha256sumline format, the*binary marker and escaped file names. - SubtleCrypto.digest on MDN — the one-shot browser API.
- SHAttered — the 2017 SHA-1 collision.