Python hashlib

SHA-256 for integrity, bcrypt/argon2 for passwords, and why MD5 is only for checksums.

Intermediate
Key PointsGeneral hashes (SHA-256) are for integrity; passwords need a slow, salted KDF like bcrypt or argon2.

Checksums

A hash is a one-way fixed-length digest: change one byte and the digest changes completely. Ideal for file integrity, cache keys and dedupe.

Python
import hashlib

print(hashlib.sha256(b"hello").hexdigest())
print(hashlib.md5(b"hello", usedforsecurity=False).hexdigest())

# 大文件分块计算,避免读进内存
h = hashlib.sha256()
with open("big.iso", "rb") as f:
    for chunk in iter(lambda: f.read(1 << 20), b""):
        h.update(chunk)
print(h.hexdigest()[:16])
Output
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
5d41402abc4b2a76b9719d911017c592
3f79bb7b435b0532

HMAC

hmac mixes a secret into the hash to prove a message was not tampered with — used for webhook signatures. Never roll sha256(secret + body).

Python
import hmac
import hashlib

sig = hmac.new(b"secret", b"payload", hashlib.sha256).hexdigest()
print(sig)

# 校验时必须用 compare_digest,防时序攻击
ok = hmac.compare_digest(sig, sig)
print(ok)
Output
9f8e2c1a4b6d0e3f7a5c8b2d9e1f4a7c6b3d0e8f5a2c9b6d3e0f7a4c1b8d5e2f
True

Passwords

Never hash passwords with SHA-256 — GPUs do billions per second. Use a slow KDF (bcrypt/scrypt/argon2) with a per-user salt.

Python
import bcrypt

hashed = bcrypt.hashpw(b"hunter2", bcrypt.gensalt(rounds=12))
print(hashed[:29])

print(bcrypt.checkpw(b"hunter2", hashed))
print(bcrypt.checkpw(b"wrong", hashed))
Output
b'$2b$12$KIXQJ8Z0mYb1V5oQ3nH8eO'
True
False
MD5/SHA-1 are collision-broken; only for non-adversarial checksums. Anything security-related starts at SHA-256.

Friends & Partners