You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Zipfile.write因文件修改日期导致压缩包哈希变化?

解决Zipfile压缩相同内容哈希不一致的问题

你猜的没错——文件的修改时间、权限等元数据是导致相同内容的文件压缩后哈希不同的罪魁祸首。zip归档里的每个文件条目都会附带这些元数据,哪怕文件内容完全一样,每次生成zip时这些动态变化的元数据都会让最终的包产生差异。

要实现“仅基于内容生成一致哈希的zip包”,核心思路是手动固定所有可变的元数据,不让这些额外信息影响最终的归档结果。下面是具体的实现方法:

具体步骤

  • 创建一个固定的ZipInfo对象,手动设置所有可能变化的元数据(比如修改时间、权限)为固定值
  • 读取文件的原始内容,通过zf.writestr()方法将内容写入zip,而不是用默认的zf.write()(后者会自动读取文件的元数据)

修改后的测试代码

import os
import hashlib
import zipfile
from io import BytesIO
from datetime import datetime

FILE_PATH = './'
SAMPLE_FILE = "zip_test123.txt"
# 创建空文件(保持原有逻辑)
new_file = os.path.join(FILE_PATH, SAMPLE_FILE)
try:
    open(new_file, 'x')
except FileExistsError:
    os.remove(new_file)
    open(new_file, 'x')

# 准备zip包
data = BytesIO()
with zipfile.ZipFile(data, mode='w') as zf:
    # 创建ZipInfo对象,指定文件名
    zip_info = zipfile.ZipInfo(SAMPLE_FILE)
    # 设置固定的修改时间(用zip格式支持的最早时间,也可设其他固定时间)
    zip_info.date_time = datetime(1980, 1, 1, 0, 0, 0).timetuple()[:6]
    # 设置固定的文件权限(普通文件的644权限)
    zip_info.external_attr = 0o644 << 16  # 外部属性需左移16位符合zip格式要求
    # 读取文件内容并写入zip
    with open(new_file, 'rb') as f:
        zf.writestr(zip_info, f.read())

zip_cntn = data.getvalue()
data.close()
print(zip_cntn)
print(hashlib.md5(zip_cntn).hexdigest())

关键细节说明

  • zip_info.date_time:必须是包含年、月、日、时、分、秒的6元组,这里固定为1980年1月1日(zip格式支持的起始时间),确保每次生成的元数据一致
  • zip_info.external_attr:存储文件权限等属性,0o644 << 16是普通文件的标准权限设置,左移16位是zip格式对属性存储的要求
  • 选用writestr()而非write():直接写入文件原始内容,避免自动读取文件的动态元数据

这样修改后,只要文件内容不变,每次生成的zip包哈希值就会完全一致了。

内容的提问来源于stack exchange,提问作者Mahyar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:27:35