下载到云服务器的文件是否完整?用 Python 标准库做 SHA-256 校验
把安装包、模型文件或备份从一台机器传到另一台机器后,文件名相同、大小相近,并不足以说明内容完全一致。一个实用做法是:传输前计算摘要,传输完成后再计算一次,并比较结果。本文给出一个无需第三方依赖的分块读取示例。
1. 分块读取,避免一次读入整个文件
将下面代码保存为 sha256_check.py:
import argparse
import hashlib
import re
def sha256_file(path):
digest = hashlib.sha256()
with open(path, "rb") as source:
for chunk in iter(lambda: source.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def main():
parser = argparse.ArgumentParser(description="Calculate or verify SHA-256")
parser.add_argument("path")
parser.add_argument("--expected", help="Expected SHA-256, 64 hexadecimal characters")
args = parser.parse_args()
expected = args.expected.strip().lower() if args.expected else None
if expected is not None and re.fullmatch(r"[0-9a-f]{64}", expected) is None:
parser.error("--expected must contain exactly 64 hexadecimal characters")
try:
actual = sha256_file(args.path)
except OSError as error:
parser.exit(2, f"Cannot read file: {error}\n")
print(actual)
if expected is not None:
if actual != expected:
parser.exit(1, "SHA-256 mismatch\n")
print("SHA-256 matches")
if __name__ == "__main__":
main()
这里使用 rb 模式读取原始字节,避免文本编码和换行转换影响结果。每次只读取 1 MiB;文件更大时,需要的读取次数增加,读取缓冲不会随文件大小无限增长。with 语句负责关闭文件。持续调用同一个摘要对象的 update,即可计算整份文件的摘要,最后用 hexdigest 得到十六进制字符串。接口行为可参阅 Python 标准库官方文档的 hashlib 章节。
2. 传输前后怎样使用
在源机器上计算摘要:
python sha256_check.py "backup.tar.gz"
记录输出的完整 64 位十六进制值。文件传到云服务器后,把该值作为 --expected 参数传入:
python sha256_check.py "backup.tar.gz" --expected 源机器输出的完整SHA256值
上面中文参数是占位说明,执行时必须替换为真实摘要。文件名含空格时保留引号。参数只接收摘要值,不要连同文件名、SHA256= 前缀一起复制。
脚本匹配成功时退出码为 0,内容不匹配时为 1,参数错误或文件无法读取时为 2。因此,它既能人工运行,也适合在传输脚本中作为后续步骤的条件:校验成功后再解压、导入或替换文件。
3. 已验证的边界情况
核心 sha256_file 函数已在 Python 3.13.1 环境中验证以下情况:
- 空文件:结果为 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855。
- 内容恰好为三个字节 abc 的文件:结果为 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad。
- 长度为 2 MiB 加 17 字节的文件:分块结果与对同一内容直接计算的摘要一致,覆盖了跨块和末尾不足一块的情形。
- 不存在的路径:核心函数抛出 FileNotFoundError,由命令行入口统一处理为读文件失败。
注意,abc 后面如果多一个换行,就已经是另一份内容,不应期待得到相同结果。上述验证针对本地文件计算,不代表已验证某种云存储传输链路。
4. 摘要能证明什么
若前后摘要不同,先核对路径、文件版本和下载是否完成,不要直接认定存储设备故障。计算摘要期间也应避免文件继续被写入,否则比较的可能不是同一个稳定版本。
摘要校验用于检查内容一致性,不等于确认发布者身份。如果文件和所谓的正确摘要都来自同一个不可信来源,即使匹配,也不能据此证明文件安全。软件来源可信度还需要结合官方渠道和签名验证判断。
实际工作中,建议将文件名、版本、大小和 SHA-256 一起记录到发布清单,方便之后定位到底传输了哪一个版本。
本文由 AI 辅助整理,核心文件摘要函数已按上述案例执行验证。
- 点赞
- 收藏
- 关注作者
评论(0)