File Hashes: The Fingerprint Every File Carries
What a file hash is, why changing a single byte changes everything, how to use one to verify a Linux ISO, and how services like VirusTotal let you look a file up without ever uploading it.
Every file on your computer has a fingerprint. You've probably seen one without realizing it: a long string of letters and numbers sitting next to a download link, the kind most people scroll straight past.
That string is a hash. And once you understand what it is, you'll start seeing it everywhere.
I've been using hashes for years in IT, mostly without thinking about it. It wasn't until I sat down to build a small tool around them that I really appreciated how simple, and how useful, the idea is.
What a Hash Actually Is
A hash function takes any file you give it, whether that's a one-line text file or a 6 GB operating system image, and boils it down to a short, fixed-length string. The one you'll see most often today is called SHA-256, and it always produces exactly 64 characters.
Here's what it looks like on Linux:
sha256sum notes.txt2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 notes.txt
A few rules make hashes useful:
- Same contents, same hash. Every time. Hash a file today, next year, or on a completely different computer, and you get the identical result.
- It only goes one way. You can't rebuild a file from its hash. The fingerprint identifies the file; it doesn't contain it.
- It's always the same size. A tiny file and a huge ISO both get 64 characters.
That's the whole trick. A hash is a short, reliable way of saying "this exact file."
Change One Byte, Change Everything
This is the part that surprised me most when I first played with it.
I created two small files. One contained the word hello. The other contained
hello followed by a newline, the invisible character you get when you press
Enter. To your eyes, they're the same file. Here are their hashes:
hello → 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hello + newline → 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
Not similar. Not slightly off. Completely different. One invisible character changed every part of the fingerprint.
The flip side is just as interesting. I created two empty files with different
names, a.txt and my notes.txt. Their hashes were identical:
e3b0c442...b855. That's the hash of nothing at all.
The filename doesn't matter. The date doesn't matter. Only the contents do.
So when people say "every file has a unique hash," the more precise version is this: identical contents always produce identical hashes, and different contents produce different ones. Two copies of the same file share a fingerprint. Change a single byte, and you get a new one.
In theory, two different files could produce the same hash. In practice, nobody has ever found two different files that do this with SHA-256. Older algorithms like MD5 and SHA-1 have been broken, though: researchers can deliberately create two files with matching hashes. That's why you'll see SHA-256 used for anything security-related today.
Did I Download the Real Thing?
Here's where hashes earn their keep.
When you download a Linux ISO, you're pulling several gigabytes across the internet, often from a mirror server run by a university or company you've never heard of. Plenty can go wrong: the download gets corrupted, a mirror serves a stale file, or someone swaps the file for something nastier.
Linux distributions solve this by publishing the hash of every official image.
- Arch Linux lists the SHA256 and BLAKE2b checksums right on its download page.
- Ubuntu publishes a file called
SHA256SUMSnext to the ISOs on releases.ubuntu.com.
Once your download finishes, you hash the file yourself and compare:
# Linux
sha256sum archlinux-x86_64.iso
# macOS
shasum -a 256 archlinux-x86_64.iso
# Windows (PowerShell)
Get-FileHash .\archlinux-x86_64.isoIf your result matches the one on the official site, character for character, you have exactly the file the developers published. If it doesn't match, delete it and download again. No exceptions.
Don't just compare the first few characters. Copy the official hash and search
for it, or let the tool do the comparison for you. On Ubuntu, sha256sum -c SHA256SUMS --ignore-missing checks your ISO against the published list and
simply prints OK.
The Catch
A matching hash proves one thing: your file matches the hash on the website. It doesn't prove the website itself is trustworthy.
That's not hypothetical. In February 2016, attackers broke into the Linux Mint website and pointed the download link for one edition at a modified ISO with a backdoor built in. If an attacker controls the page, they can change the hash right alongside the file.
This is why distributions also sign their checksums with a cryptographic
key, and why Ubuntu ships a SHA256SUMS.gpg file and Arch publishes a PGP
signature. Verifying those signatures is the next level up, and both
Ubuntu and
Arch have official guides. For most people,
checking the hash is the habit worth building first.
Looking a File Up by Its Hash
Because a hash identifies a file's contents, you can use it to ask questions about a file without handing the file over. That's exactly what VirusTotal lets you do.
VirusTotal runs files through around 70 antivirus engines from different security companies and keeps the results. Paste a hash into its search bar, and if anyone in the world has ever uploaded that exact file, you'll see what each engine thought of it.
To test this, I used the EICAR test file. It's a harmless string of text that every antivirus product agrees to flag, so people can check their setup without touching real malware. Searching its hash came back with nearly every engine marking it as malicious, which is exactly what it's designed to do.
Searching by hash is private. VirusTotal learns a 64-character string and nothing else. Uploading a file is different: uploaded files are shared with the security community and can be downloaded by researchers. Never upload anything private, like documents, spreadsheets or work files. Check the hash first.
The Results Are Clues, Not Verdicts
This is the part I want to stress, because it's easy to take a number on a screen as the final answer. It isn't.
- False positives happen. Legitimate tools get flagged all the time, especially admin, networking and security utilities that behave a bit like malware by design. One or two detections out of seventy is often noise.
- False negatives happen too. Brand-new malware can show zero detections simply because no engine has learned to recognize it yet. A clean result means "nothing known," not "safe."
- "Not found" doesn't mean clean. If VirusTotal has never seen a file, that tells you nothing about it either way. Unknown is not the same as safe.
- Results change over time. Engines update constantly. A file that looked clean last month may be flagged today, and the reverse. Check when it was last analyzed.
Look at which engines flag a file and what name they give it, not just the count. If several major vendors agree on a specific malware family, take it seriously. If one obscure engine calls it "generic suspicious," dig a little deeper before you panic.
VirusTotal is a great second opinion. It's not a replacement for your own judgment.
hash_ls: Doing This From the Terminal
All of this is easy enough to do by hand for one file. But I wanted something
quicker for a whole folder, so I built a small tool called hash_ls.
You run it inside any folder, and it lists every file with its SHA-256 hash and size. Pick a number, and it checks that file against VirusTotal:
# SHA256 Size FileName
1 275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f 68 B eicar.com
2 28197c5ac7a9c4c4a3a4b2b08bdbdff1a53cd5a79a37c687833c65f3d9612929 4.7 MB mb.bin
Enter a file # to check on VirusTotal (Q to quit): 1
Checking eicar.com...
65/68 engines flagged malicious, 0 suspicious
A few things I cared about when building it:
- Only the hash is ever sent. Your files never leave your machine.
- Unknown files are reported as unknown, never as clean.
- Results are color-coded, and you can open the full VirusTotal report in your browser with one keypress.
- It works on Linux and macOS, and it only needs a free VirusTotal API key for lookups. It asks for the key once and stores it so only your user can read it.
It's part of my Bash-Toolkit on GitHub. The README walks through installation and setup. If you're on Windows, the original version lives in my PowerShell Toolkit.
Build the Habit
Hashes are one of those quiet pieces of computing that hold a lot together. They're how package managers know an update wasn't tampered with, how backup tools spot changed files, and how you can confirm that a 6 GB download is exactly what it claims to be.
Next time you download an ISO, take thirty seconds and check the hash. Next time a file looks suspicious, look it up before you open it.
Small habit. Big difference.