Python 计算文件 MD5/SHA256 校验值 批量对比教程
用 Python hashlib 流式计算大文件的 MD5/SHA256,避免一次性读爆内存,批量扫描整个文件夹输出校验清单,校验文件完整性、去重、比对网盘同步。
场景痛点
从网盘下载的安装包、从客户那传来的合同,怕中途损坏或被篡改,要核对官方公布的 MD5。手动下 md5sum 工具一个个跑,文件夹里上百个文件根本对不过来。用 Python 流式读取,边读边算哈希,几百 MB 大文件也不会爆内存,批量输出到 CSV,再和官方值一比对就知道哪个坏了。
用到的库
# 标准库,无需安装
# pip install 无需额外依赖
完整代码
# -*- coding: utf-8 -*-
# 批量计算文件夹下每个文件的 MD5 / SHA256,输出 CSV
import os
import csv
import hashlib
def hash_file(path, algo="md5", chunk=65536):
"""流式读取,chunk=64KB,大文件不爆内存"""
h = hashlib.new(algo)
with open(path, "rb") as f:
for block in iter(lambda: f.read(chunk), b""):
h.update(block)
return h.hexdigest()
def scan_folder(root, out_csv):
rows = []
for dirpath, _, files in os.walk(root):
for fn in files:
p = os.path.join(dirpath, fn)
rel = os.path.relpath(p, root)
try:
md5 = hash_file(p, "md5")
sha = hash_file(p, "sha256")
size = os.path.getsize(p)
rows.append([rel, size, md5, sha])
print(f"{rel} md5={md5[:12]}...")
except Exception as e:
print(f"跳过 {rel}: {e}")
with open(out_csv, "w", newline="", encoding="utf-8-sig") as f:
w = csv.writer(f)
w.writerow(["相对路径", "字节", "MD5", "SHA256"])
w.writerows(rows)
print(f"完成 {len(rows)} 个文件 -> {out_csv}")
def find_duplicates(csv_path):
"""读 CSV,按 MD5 找重复文件"""
seen = {}
with open(csv_path, encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
for row in reader:
md5 = row["MD5"]
seen.setdefault(md5, []).append(row["相对路径"])
for md5, paths in seen.items():
if len(paths) > 1:
print(f"重复 {md5[:12]}: {paths}")
if __name__ == "__main__":
scan_folder("./downloads", "./hash_report.csv")
find_duplicates("./hash_report.csv")
代码讲解
hashlib.new("md5")拿到哈希对象,h.update(block)分块喂数据,h.hexdigest()输出十六进制字符串。iter(lambda: f.read(65536), b"")是经典流式写法:每次读 64KB,读到空为止。哪怕文件 10GB,内存占用也只有 64KB。- SHA256 比 MD5 更抗碰撞,但 MD5 快一倍,日常校验完整性 MD5 够用;要防篡改用 SHA256。
os.walk递归扫所有子目录,CSV 里写相对路径,方便和别人对清单。find_duplicates按 MD5 分组,同 MD5 的文件列出来,就是一份去重清单。
运行结果
把待校验的文件放进 ./downloads,运行后生成 hash_report.csv,每行是相对路径、大小、MD5、SHA256。终端同时打印 MD5 重复项,一键找出冗余文件。
注意事项
- 不要
open(path).read()一次性读文件,几 GB 的视频会直接 MemoryError。 - MD5 已被证明可碰撞,但用于"判断文件有没有损坏"足够;用于安全签名必须 SHA256。
- 跨平台对清单时注意行尾、时间戳差异,只看 MD5/SHA256 列即可。
- 扫描云盘同步目录时,符号链接会被当成普通文件,可能重复计算,必要时
os.path.islink跳过。

更新时间:2026-09-14 20:26:39
上一篇:Python 文件备份到云盘网盘同步思路 自动增量备份