Hash Notes — A Hashing & Cryptography Field Guide

Fundamentals

What a Hash Function Is

A function that maps input of any size to a fixed-size fingerprint — deterministic, fast, and (for cryptographic hashes) impossible to reverse or collide on purpose.

A hash function takes an input of any length — a password, a URL, a 4 GB video — and returns an output of a fixed length, called the hash, digest, or fingerprint. SHA-256 always returns 256 bits (64 hex characters), whether you feed it one byte or a terabyte.

SHA-256("hello")  = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-256("hello!") = ce06092fb948d9ffac7d1a376e404b26b7575bcc11ee05a4615fef4fec3a308b
SHA-256(<the entire text of Wikipedia>) = still exactly 64 hex characters

Almost every use of hashing in this guide — shortening strings, storing passwords, detecting tampering, distributing data across servers — comes from a handful of properties.

Fig. 1 — The avalanche effect — change one character, flip half the bits

SHA-256(A)

SHA-256(B)

0 of 256 bits differ (0%). A good hash flips about half the output bits for any change to the input — the avalanche effect — so similar inputs give no hint of being similar.

The properties every hash has

Property Meaning What it enables
Deterministic Same input → same output, every time, on every machine. Lookups, cache keys, dedup, comparing without storing the original.
Fixed output size Output length doesn’t depend on input length. Shortening strings, fixed-width index columns.
Fast to compute Linear in input size; GB/s for the fast ones. Checksumming big files, hash tables.
Uniform distribution Outputs are spread evenly across the output space. Even sharding/bucketing; few accidental collisions.

The extra properties of a cryptographic hash

A cryptographic hash (SHA-256, SHA-3, BLAKE2) adds guarantees that hold even against an attacker who is actively trying to break them:

Property Meaning Breaks if it fails
Preimage resistance (one-way) Given a hash h, you can’t find any input with hash(x) = h. Password storage, commitments.
Second-preimage resistance Given an input x, you can’t find a different y with the same hash. File integrity: an attacker could swap your file for theirs.
Collision resistance You can’t find any two inputs x ≠ y with the same hash. Digital signatures, certificates, content addressing.
Avalanche effect Changing one input bit flips ~50% of output bits. Similar inputs leak nothing about each other.

A hash is not encryption

There is no key and no “unhash” function. The only way to go from a hash back to an input is to guess inputs, hash each guess, and compare. That’s why:

  • Hashing a long random value (an API token, a file) is effectively irreversible.
  • Hashing a short predictable value (a password, a phone number, an SSN — only ~10⁹ possibilities) is not private: an attacker hashes all billion candidates in seconds. That’s what salting and slow hashes are for (see Salting & Password Hashing).

Cryptographic vs. non-cryptographic

Both are “hash functions,” but they’re built for different jobs:

Non-cryptographic Cryptographic
Examples CRC32, MurmurHash3, xxHash, FNV, String.hashCode() SHA-256, SHA-3, BLAKE2/3
Goal Spread inputs evenly, as fast as possible Resist a deliberate attacker
Speed Very fast (10+ GB/s for xxHash) Fast (~1–2 GB/s for SHA-256 with hardware support)
Safe with untrusted input? No — attackers can craft collisions Yes
Typical use Hash tables, Bloom filters, partitioners, checksums Integrity, signatures, IDs from untrusted data, HMAC

When in doubt, use SHA-256. It’s fast enough for nearly everything, and it never becomes a security bug later when someone feeds it user input.