I download a file. The website has a SHA-256 hash next to it. I want to verify it. So I run sha256sum, get a wall of hex, paste the expected hash next to it, and squint at two 64-character strings trying to spot any difference.
For a quick one-off verification, the native tools are clunky. On Linux it's sha256sum, on macOS it's shasum -a 256, on Windows it's Get-FileHash. Different syntax, same manual effort.
(Yes, sha256sum -c exists. But it expects a properly formatted checksum file — not a hash you just copied off a download page.)
So I ended up building a small CLI for this: verify-integrity.
What it does
Instead of just outputting a string or failing quietly, it shows you a character-by-character diff so you can see exactly where they diverge:
$ npx verify-integrity ./myfile.zip 3a4c9877b483ab46d7c3fbe165a0db275e1ae3cfe56a5657e5a47c2f99a99d1e
✖ Hashes did not match! Integrity verification failed.
Expected: 3a4c9877b483ab46d7c3fbe165a0db275e1ae3cfe56a5657e5a47c2f99a99d1e
Generated: 3a4c9877b483ab46d7c3fbe165a0db275e1ae3cfe56a5657e5a47c2f99a99dab
Matching characters are dimmed, mismatching ones are bold. Useful when you're trying to figure out if you fat-fingered something or if the file is genuinely corrupted.
On a match:
✔ Hashes matched! Integrity verified.
Generated hash: 3a4c9877b483ab46d7c3fbe165a0db275e1ae3cfe56a5657e5a47c2f99a99d1e
Or, skip saving the file entirely and pipe straight from curl:
curl -sL https://example.com/file.zip | verify-integrity - 3a4c9877b483ab46...
Pass - as the file path and it reads from stdin. Standard Unix convention, works naturally in pipelines.
The algorithm situation
SHA-256 is the default since that's what most things use these days, but you can switch:
verify-integrity -a sha512 ./file.tar.gz 9b71d224bd62f378...
MD5 and SHA-1 are supported too for legacy stuff, though the README is upfront about the fact that MD5 is broken and SHA-1 is weak. I didn't want to pretend otherwise.
Partial hashes
Occasionally you'll see a shortened hash prefix in release notes or some internal tool, not the full hash. The --partial flag handles that:
verify-integrity -p ./myfile.zip abcd1234
It checks whether the generated hash starts with your prefix. There's a warning built in if your prefix is under 8 characters — short enough that false positives become a real concern.
For scripting
--quiet kills all output and communicates purely through exit codes. 0 for a match, 1 for a mismatch.
verify-integrity -q ./release.tar.gz 3a4c9877b483ab46... && deploy.sh
Drop it into any script or CI pipeline without worrying about parsing output.
Should you use it over the native tools?
If the native tools are already muscle memory for you, honestly just keep using them.
But if you switch between machines, script things cross-platform, or just want a clear pass/fail without the manual comparison — give it a shot. The npx invocation means you don't even have to commit to installing it.
It's fully open-source. Feel free to audit the code, fork it, or open an issue over on GitHub.
Try it yourself:
npx verify-integrity <file> <expected_hash>
Would love to hear what you think.
Top comments (0)