DEV Community

AI Dev Hub
AI Dev Hub

Posted on

How I verify 4.7 GB downloads with a hash generator in 2026

How I verify 4.7 GB downloads with a hash generator in 2026

Use SHA-256 for anything you actually care about, and paste the vendor's published checksum into a comparison field rather than eyeballing 64 hex characters. MD5 and SHA-1 still catch accidental corruption fine, they just fall apart against a deliberate attacker. A browser-based generator hashes files locally through the Web Crypto API, so the bytes never leave your laptop.

The hash generator I link to below is one I built. I'd been through six or seven online checksum pages and every one of them either uploaded the file to somebody's server or quietly choked past a few megabytes. Mine is free, runs entirely client-side, no signup, no upload. If you know a better one, tell me and I'll link to that instead.

The 43 minutes I lost to a half-downloaded archive

On March 11, 2026 I spent 43 minutes debugging a Postgres restore that kept dying at exactly the same point in the dump. Same error every time. I rebuilt the container. I bumped the memory limit. I read the pg_restore source, which is a thing I do when I've run out of reasonable ideas.

The dump file was 4.7 GB. The one I'd downloaded was 4.68 GB. Our S3-fronted CDN had truncated it, returned a 200, and everything downstream treated it as a complete file. There was a .sha256 sitting right next to it in the bucket the whole time. I'd never checked it, because checking it meant either remembering the exact shasum flag or finding one of those upload-your-file websites, and both of those felt like more friction than just retrying the restore.

That instinct cost me 43 minutes. It's a bad instinct and I've mostly trained it out of myself since.

The general shape of the problem: you have a file, someone published a hash for it, and you need to know whether those two agree. That's it. It's a five-second operation that people skip constantly because the tooling around it is worse than it needs to be. Windows users get certutil -hashfile file SHA256, which nobody remembers. macOS gives you shasum -a 256. Linux gives you sha256sum. Three different commands for one job, and then you still have to compare two 64-character strings by staring at them, which is exactly the kind of task human eyes are terrible at.

I've watched competent engineers check the first four and last four characters and call it a match. Honestly I've done it too.

What's actually happening when you hash a file

A hash function eats arbitrary bytes and spits out a fixed-length digest. SHA-256 always produces 256 bits, 64 hex characters, whether you feed it an empty file or a 4.7 GB one. Change a single bit anywhere in the input and roughly half the output bits flip. That avalanche property is what makes hashes useful for integrity checks: there's no such thing as a "close" match.

The part that matters for tooling is that hashing is streaming. You don't need the whole file in memory. You feed the hasher chunks, it updates internal state, and at the end you ask for the digest. That's why a well-built browser tool can hash a multi-gigabyte file without the tab dying, and why the upload-based sites are doing something unnecessary.

Here's the CLI version I keep in my dotfiles, which is what I reach for when I'm already in a terminal:

const { createHash } = require('node:crypto');
const { createReadStream } = require('node:fs');

function hashFile(path, algo = 'sha256') {
  return new Promise((resolve, reject) => {
    const hash = createHash(algo);
    const stream = createReadStream(path);
    stream.on('data', chunk => hash.update(chunk));
    stream.on('error', reject);
    stream.on('end', () => resolve(hash.digest('hex')));
  });
}

const [file, expected] = process.argv.slice(2);

hashFile(file).then(digest => {
  console.log(digest);
  if (expected) {
    const ok = digest.toLowerCase() === expected.toLowerCase();
    console.log(ok ? 'MATCH' : 'MISMATCH');
    process.exit(ok ? 0 : 1);
  }
});
Enter fullscreen mode Exit fullscreen mode

Run it as node hash.js backup.dump a1b2c3... and it exits non-zero on a mismatch, which means you can drop it straight into a CI step or a deploy script. On my machine that hashes the 4.7 GB dump in about 11 seconds, almost all of it disk-bound.

In the browser the equivalent is crypto.subtle.digest('SHA-256', buffer), with one annoying catch: SubtleCrypto has no streaming interface. For big files you either read the whole thing into an ArrayBuffer (fine up to a point, then the tab gets unhappy) or ship a WASM implementation that does support incremental updates. I went with WASM after the naive version fell over on a 2 GB file, which took me most of a Saturday to figure out and was genuinely irritating at the time.

How it stacks up against the alternatives

Three realistic options if you need a hash right now. I've used all three in anger.

Browser tool (client-side) Native CLI (shasum, certutil) Upload-based web tools
File leaves your machine No No Yes
Works on a locked-down work laptop Yes Usually Yes
Command to memorize None One per OS None
Compare against expected hash Built in Manual, or --check with a file Rarely
Practical file size ceiling ~4 GB in-tab Unlimited Often 50-100 MB
Multiple algorithms at once Yes One flag per run Sometimes

The CLI wins on raw capability and it's what I use for anything scripted. The browser tool wins on the specific case that comes up most often for me: I'm on a machine I don't fully control, I have one file, I have one expected hash, and I want an unambiguous yes or no in under ten seconds. That's the hash generator I built. Drop the file in, paste the published checksum into the compare field, and it goes green or red. No eyeballing hex.

The upload-based sites are the ones I'd actively steer people away from. Sending a database dump or a signed binary to a stranger's server so they can run hashlib.sha256() on it is a trade nobody should make, and several of those sites are ad-funded, which tells you what the business model is.

When a hash generator is the wrong tool

This is where I'd push back on my own article a bit, because checksums get reached for in situations they don't fit.

Password storage is the big one. Never store a raw SHA-256 of a password. Fast hashes are fast for attackers too, and a modern GPU rig will do billions of SHA-256 guesses per second. Use bcrypt, scrypt, or Argon2id, which are deliberately slow and salted. If you find yourself typing sha256(password) in production code, stop.

Verifying a download against an attacker is subtler. A published SHA-256 only helps if the attacker couldn't also edit the page that publishes it. If someone compromises the mirror, they change the file and the listed hash together and you're none the wiser. What actually defends against that is a GPG signature over the checksum file, verified against a key you obtained separately. The hash is one layer. Treat it as protection against corruption and truncation, which is what it's genuinely excellent at.

MD5 and SHA-1 both have practical collision attacks. Two different files with the same MD5 can be constructed in seconds on a laptop. That doesn't make MD5 useless for detecting a flaky network transfer, and plenty of internal systems still use it as a cheap content key. It does make it worthless as a security boundary. If a vendor in 2026 publishes only an MD5, that tells you something about how much attention they pay to this.

Also: if you're comparing thousands of files, don't do it by hand in a browser. Write the loop. Use sha256sum --check against a manifest. The tool is for the one-off case, and I'd rather say that plainly than pretend it scales.

FAQ

Q: Which algorithm should I default to?
A: SHA-256. It's fast enough that the difference from MD5 is irrelevant on any modern CPU, and it has no known practical collision attacks. Use SHA-512 if a vendor publishes it, since it's actually faster than SHA-256 on 64-bit hardware.

Q: Is a client-side browser tool really not uploading my file?
A: Open the network tab and watch. There should be zero requests while hashing. That's the test I'd apply to any tool making this claim, including mine.

Q: Why do my hash and the published one differ in case?
A: Hex digests are case-insensitive. Some tools output uppercase, some lowercase. Any comparison worth using normalizes both sides before checking.

Q: Can I hash text instead of a file?
A: Yes, and it's a common way to sanity-check an API's signing logic. Watch for a trailing newline, which is the cause of maybe 80% of "why doesn't my HMAC match" bugs I've helped debug.

Written with AI assistance and human review. Try the tool at aidevhub.io/hash-generator.

Top comments (0)