hashlib 是 Python 内置的哈希库,无需安装即可生成 MD5、SHA-256、SHA-512 等摘要,常用于文件校验、密码加盐、完整性验证。哈希不可逆且对输入极其敏感。
核心概念
- 摘要算法对输入字节计算定长输出(MD5 → 128 bit,SHA-256 → 256 bit)
- 相同输入 + 相同算法 → 哈希一致;输入微小改动 → 哈希完全不同
- 单向不可逆,只能用于校验/比对,不能反推原文
- 字符串必须先
.encode("utf-8")转为字节才能传给update()
常用算法
| 算法 | 摘要位数 | 十六进制长度 | 速度 | 安全性 | 主要用途 |
|---|---|---|---|---|---|
md5() | 128 | 32 | 最快 | 低(已破解) | 文件校验、缓存键 |
sha1() | 160 | 40 | 快 | 低 | 兼容旧场景,已不推荐 |
sha256() | 256 | 64 | 中 | 高 | 默认选择 |
sha512() | 512 | 128 | 较慢 | 最高 | 极高安全需求 |
字符串哈希
两种等价写法,简洁版更常用:
import hashlib
data = "hello world"
# 标准写法
md5 = hashlib.md5()
md5.update(data.encode("utf-8"))
print(md5.hexdigest())
# 简洁写法
print(hashlib.sha256(data.encode()).hexdigest())大文件分块
避免一次性读入大文件占满内存:
def file_hash(path: str, algo: str = "sha256") -> str:
h = hashlib.new(algo)
with open(path, "rb") as f:
while chunk := f.read(64 * 1024):
h.update(chunk)
return h.hexdigest()密码场景:必须加盐
直接哈希密码可被彩虹表反查。每个用户配独立随机盐可让相同密码产生不同结果:
import os, hashlib
def hash_password(password: str, salt: bytes | None = None) -> tuple[bytes, str]:
salt = salt or os.urandom(16)
digest = hashlib.sha256(salt + password.encode()).hexdigest()
return salt, digest盐的作用
盐不需要保密,可以与哈希一起存储。它的价值是打散输入、防批量破解,而不是加密。 真正提供”难以暴力破解”特性的是慢哈希算法(bcrypt / Argon2 / scrypt),SHA-256 + 盐只是入门级方案。生产系统应优先使用
passlib/argon2-cffi。
注意点
- 字符串先编码再哈希,否则报
TypeError - MD5/SHA-1 不要用于密码或对抗性场景
update()可多次调用,等价于将所有数据拼接后一次性update- 比较哈希时使用
hmac.compare_digest,避免时序攻击