功能说明
file_checksum 以二进制模式打开文件,循环读取固定大小的块并更新哈希对象,因此不会把整个文件载入内存,适合校验大文件、下载包和备份镜像。默认使用 SHA-256,也可以通过 algorithm 指定 hashlib 支持的算法,例如 sha1、sha512 或 md5。chunk_size 可以按磁盘和网络特性调整。
verify_checksum 先计算实际摘要,再用 hmac.compare_digest 与期望值比较。这个比较是常量时间的,可以避免通过响应时间推测摘要内容。比较前会统一去掉期望值两端空白并转成小写,兼容常见的大写十六进制表示。
关键代码
核心循环使用海象运算符逐块读取,读到空字节串时结束:
with file_path.open("rb") as handle:
while chunk := handle.read(chunk_size):
digest.update(chunk)
文件不存在、权限不足或其他 I/O 错误会被包装成 ChecksumError,并保留原始异常作为 __cause__。不支持的算法同样转换成本模块的错误类型,调用方只需捕获一种异常。
使用注意
校验和只能检测意外损坏,不能替代签名或 MAC;如果攻击者可以同时替换文件和摘要,校验和无法证明来源可信。MD5 和 SHA-1 已不适合安全用途,仅可用于兼容旧系统。读取过程中文件可能被其他进程修改,校验结果会不确定;需要强一致时应先加锁或复制快照。
chunk_size 必须为正整数,过小会增加系统调用次数,过大则增加单次内存占用。函数接受 str 或 Path,其他类型交给 Path 构造并可能抛 TypeError。verify_checksum 不会自动识别摘要算法,调用方必须保证算法与期望值匹配。异常消息包含文件路径,记录日志时要注意路径隐私。
验证方式
示例在临时目录写入约 11 KB 的重复内容,以 256 字节分块计算 SHA-256,得到 64 位十六进制摘要。用同一摘要验证应返回 True,用全零摘要验证应返回 False。传入不存在的算法名应捕获并输出 unsupported algorithm: not-a-hash。可以再修改文件一个字节,确认摘要变化且验证失败。