用 Python 校验下载文件的 SHA-256

举报
yd_251192881 发表于 2026/11/07 15:24:43 2026/11/07
【摘要】 用 Python 标准库分块计算文件 SHA-256,校验下载内容,并区分摘要格式错误、内容不一致和文件读取失败。示例包含可运行的检查代码。

下载脚本、安装包或数据文件后,可以计算 SHA-256,并与发布方提供的摘要比较。这个过程能发现传输损坏或文件被替换的情况,但不能证明文件来源可信;摘要本身也需要来自可信渠道。

下面的示例分块读取文件,避免把大文件全部放入内存。它还会检查期望摘要的格式,减少因为空白、字母大小写或长度错误造成的误判。

from hashlib import sha256
from pathlib import Path


def file_sha256(path: Path, chunk_size: int = 1024 * 1024) -> str:
    if chunk_size <= 0:
        raise ValueError("chunk_size 必须大于 0")

    digest = sha256()
    with path.open("rb") as source:
        while chunk := source.read(chunk_size):
            digest.update(chunk)
    return digest.hexdigest()


def verify_file(path: Path, expected: str) -> tuple[bool, str]:
    expected = expected.strip().lower()
    if len(expected) != 64 or any(c not in "0123456789abcdef" for c in expected):
        raise ValueError("SHA-256 摘要必须是 64 位十六进制字符串")

    actual = file_sha256(path)
    return actual == expected, actual


if __name__ == "__main__":
    path = Path("download.zip")
    ok, actual = verify_file(
        path,
        "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    print(f"SHA-256: {actual}")
    print("校验通过" if ok else "校验失败")

sha256() 返回的是哈希状态对象,read() 每次只读取一个数据块并交给 update()。因此,内存占用主要取决于 chunk_size,不会随文件大小线性增长。示例默认每块读取 1 MiB,对小文件也能正常工作。

verify_file() 先规范化期望值,再检查它是否为 64 位十六进制字符串。真实的摘要比较使用不区分大小写的十六进制字符;统一转成小写后比较即可。格式错误会直接抛出 ValueError,不会悄悄返回“失败”,这样可以区分输入错误和内容不一致。

可以用标准库做一个小规模检查:

import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as directory:
    sample = Path(directory) / "sample.bin"
    sample.write_bytes(b"hello\n")

    ok, actual = verify_file(
        sample,
        "5891B5B522D5DF086D0FF0B110FBD9D21BB4FC7163AF34D08286A2E846F6BE03",
    )
    assert ok is True
    assert actual == "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03"

    ok, _ = verify_file(sample, "0" * 64)
    assert ok is False

实际使用时,还要处理文件不存在、没有读取权限、磁盘 I/O 错误和下载不完整等情况。它们会以 FileNotFoundError、PermissionError 或 OSError 等形式出现,调用方应保留错误信息,方便定位问题。校验通过只说明当前文件与给定摘要一致,不能替代 HTTPS、签名验证或可信发布流程。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。