Hash Notes — A Hashing & Cryptography Field Guide

Fundamentals

Choosing a Hash Algorithm

MD5, SHA-1, SHA-256, SHA-3, BLAKE3, xxHash, bcrypt, Argon2 — which family each belongs to, which are broken, and which to reach for by default.

There are four families of hash function, and most mistakes come from using one family for another family’s job — a fast hash for passwords, a non-cryptographic hash on attacker input, or a slow password hash for a hash table.

Fig. 1 — The four families — click any algorithm
Non-cryptographic (fast)CRC3232-bitMurmurHash332/128-bitxxHash / XXH364/128-bitCryptographic — brokenMD5128-bitSHA-1160-bitCryptographic — use theseSHA-256256-bit (SHA-2)SHA-512512-bit (SHA-2)SHA-3224–512-bitBLAKE2 / BLAKE3variablePassword hashing (slow on purpose)Argon2idmemory-hardbcryptcost factorscryptmemory-hardPBKDF2iterations
Click an algorithm for details.
RecommendedBroken for securityFine for its niche

Quick-reference table

Algorithm Output Status Use it for
CRC32 32 bits Checksum only Detecting accidental corruption (zip, Ethernet, PNG)
MurmurHash3 32 / 128 bits Non-crypto Hash tables, Bloom filters, partitioning
xxHash (XXH3) 64 / 128 bits Non-crypto Fast checksums, dedup of trusted data
MD5 128 bits Broken (collisions in seconds) Legacy compatibility, non-adversarial fingerprints only
SHA-1 160 bits Broken (SHAttered, 2017) Nothing new; legacy (old git, old TLS)
SHA-256 / SHA-512 256 / 512 bits Secure The default for integrity, IDs, HMAC, signatures
SHA-3 224–512 bits Secure Where a non-SHA-2 design is required
BLAKE2b / BLAKE3 variable Secure When speed matters or you want a custom output length
bcrypt 184 bits (60-char string) Secure, slow by design Passwords
Argon2id configurable Secure, slow + memory-hard Passwords (current best practice)

The default answers

  • Need a general-purpose hash? SHA-256.
  • Need it faster, still secure? BLAKE3 (or BLAKE2b — built into Python’s hashlib).
  • Hashing a password? Argon2id, or bcrypt if that’s what your framework ships.
  • Only bucketing data you control, need max speed? xxHash / MurmurHash3.
  • Need to prove who created the hash? That’s not a hash — use HMAC-SHA256.

What “broken” means for MD5 and SHA-1

Both are broken for collision resistance: an attacker can construct two different inputs with the same hash. In 2008 researchers used MD5 collisions to forge a trusted CA certificate; in 2017 Google published two different PDFs with the same SHA-1 hash.

They are not (practically) broken for preimage resistance — given just a hash, nobody can find an input that produces it. That’s why MD5 is still acceptable as a cache key or ETag for data no attacker controls. But “acceptable in a narrow case” is a maintenance trap: code outlives its context. If you’re writing something new, the speed difference no longer justifies the risk — use SHA-256 or BLAKE3.

Why speed is good — except for passwords

For most uses, a faster hash is strictly better. For passwords it’s the opposite: an attacker who steals your database guesses passwords by hashing candidates, and their guess rate is limited only by your hash’s speed.

Hash Approximate guesses/second on one high-end GPU
MD5 ~150 billion
SHA-256 ~20 billion
bcrypt (cost 12) ~thousands
Argon2id (64 MB memory) ~hundreds or fewer

(Orders of magnitude only — exact figures vary by hardware and parameters, but the gap of six to eight orders of magnitude is the point.) A password that would fall in a second under SHA-256 takes years under Argon2. See Salting & Password Hashing.