What is a hash function, and why can it not be reversed?
A hash function turns any input into a fixed-length fingerprint. The same input always gives the same output, and the output reveals nothing about the input — there is no reverse operation, only guessing.
Updated 2026-08-22
Hashing is not encryption
This is the distinction everything else depends on. Encryption is reversible by design: it takes data and a key, produces ciphertext, and the same key turns it back. The entire point is that the original can be recovered by whoever holds the key.
Hashing has no key and no reverse operation. It takes an input of any length and produces a fixed-length output — 256 bits for SHA-256, whatever the input was. A one-byte file and a two-gigabyte video both produce exactly 64 hexadecimal characters. Information is destroyed in the process, and it cannot be recovered because it is no longer there.
That sounds like a weakness and is the entire feature. A system that needs to check whether you know a secret, without ever storing the secret, wants exactly this. It stores the hash, hashes what you typed, and compares. If the database leaks, the attacker has fingerprints rather than passwords.
The other property that matters is determinism. The same input always produces the same output, everywhere, forever. That is what lets a hash act as an identifier — for a file, for a block in a chain, for an entry in a lookup table — and it is why a download page can publish a checksum and let you verify the file arrived intact.
Collisions, and why old algorithms died
There are infinitely many possible inputs and a finite number of possible outputs, so different inputs must sometimes produce the same hash. These are collisions, and their existence is a mathematical certainty rather than a flaw.
What matters is whether anyone can produce one deliberately. For a well-designed function with a 256-bit output, finding a collision by brute force would require on the order of 2^128 attempts — a number large enough that the energy cost alone puts it out of reach. The function is considered broken when a shortcut is discovered that reaches a collision far faster than that.
This is what happened to MD5 and SHA-1. MD5 collisions became practical in 2004 and can now be produced in seconds on ordinary hardware. SHA-1 fell in 2017, when researchers produced two different PDF files with the same hash. Both are still fine for a non-security checksum — detecting accidental corruption in a transfer — and neither should ever be used where an attacker might benefit from substituting one file for another.
The practical rule is straightforward. Use SHA-256 or better for anything where the answer matters. Treat an MD5 hash you find published as evidence the page is old, and treat software still using MD5 for signatures as a warning about the rest of its choices.
Why a plain hash is wrong for passwords
Storing passwords as SHA-256 hashes is far better than storing them in plain text and still not acceptable, for two reasons that compound each other.
The first is speed. General-purpose hash functions are designed to be fast, because they are used on large files and in tight loops. Modern hardware computes billions of SHA-256 hashes per second, so an attacker with a leaked database can test every word in every dictionary, every common password, and every predictable mutation of both, in a matter of hours.
The second is that the same password produces the same hash for everyone. That makes precomputation worthwhile: a table of hashes for millions of common passwords can be built once and reused against every database that leaks afterwards. The defence is a salt — a unique random value stored alongside each password and mixed into the hash — which makes every hash unique even when two users choose the same password, and makes precomputed tables useless.
The complete answer is a password hashing function designed for the job: bcrypt, scrypt or Argon2. These are deliberately slow and, in the case of scrypt and Argon2, deliberately memory-hungry, which blunts the advantage of specialised cracking hardware. Their cost is adjustable, so it can be raised as hardware improves. Choosing one of these over SHA-256 is not a small optimisation; it is the difference between a leaked database being an inconvenience and a catastrophe.
What hashes are good for
File integrity is the most visible use. A project publishes the SHA-256 of a download, and you can hash the file you received and compare. If they match, the file is byte-identical to what was published, which catches both a corrupted transfer and a tampered mirror. This only helps if the checksum reaches you by a route the attacker does not control, which is why checksums served over HTTPS from the project itself are worth more than one sitting beside the file on a mirror.
Deduplication and lookup are the quiet everyday uses. Content-addressed storage names a file by its hash, so identical files store once automatically. Git identifies every commit, tree and blob the same way, which is what makes a repository verifiable — change any byte of history and every hash after it changes.
Digital signatures work by hashing first. Signing a large document directly would be slow, so the document is hashed and the small fixed-length hash is signed instead. This is exactly why a broken hash function breaks signatures: if an attacker can find two documents with the same hash, a signature on one is a valid signature on the other.
What hashes are not for is hiding data you need back. If you find yourself wanting to reverse a hash, the design is wrong somewhere — either the value should have been encrypted, or it should have been stored and looked up. There is no reversing step to find.