临时文件与哈希计算异常:为何文件哈希值相同且数量不符?
问题分析与解决方案
一、所有文件哈希值相同的原因
你的代码计算哈希时用了hashlib.sha256(b'{f}'),这里的b'{f}'是固定的字节字面量,不管循环变量f是什么值,始终是对字符串"{f}"的字节形式计算SHA256,所以所有结果完全一致。
如果是要计算文件名的哈希,应该把文件名转成字节:
hashlib.sha256(f.encode()).hexdigest()
如果是要计算文件内容的哈希(更常见的需求),需要读取文件内容:
def calculate_file_hash(file_path): sha256 = hashlib.sha256() with open(file_path, 'rb') as f: while chunk := f.read(4096): # 分块读取大文件 sha256.update(chunk) return sha256.hexdigest()
二、文件数量不符与报错的原因
1. 遍历目录错误
main()函数最后进入了project-configuration/nitpick目录,但result()里执行了os.chdir("../.."),回到了tempdir目录,此时os.listdir()遍历的是tempdir里的内容(比如下载的zip包、解压的文件夹),而不是你预期的nitpick下的文件。
2. 错误的文件删除操作
代码里执行os.remove("tempfile"),但整个流程中从未创建过名为tempfile的文件,所以会触发文件不存在的错误,导致程序提前终止,无法输出完整的24个哈希值。
3. 循环次数与预期不符
你预期输出24个哈希值,单次处理8个的话需要循环3次,但代码里是range(2),仅循环2次。
修正后的代码示例
import asyncio import wget import hashlib import os import zipfile async def main() -> str: url = "https://gitea.radium.group/radium/project-configuration/archive/master.zip" temp_dir = 'tempdir' if not os.path.isdir(temp_dir): os.makedirs(temp_dir) os.chdir(temp_dir) # 避免重复下载 zip_name = "project-configuration-master.zip" if not os.path.exists(zip_name): wget.download(url) # 安全解压文件 with zipfile.ZipFile(zip_name, 'r') as zip_ref: zip_ref.extractall('.') # 进入目标目录并返回路径 nitpick_dir = os.path.join("project-configuration", "nitpick") os.chdir(nitpick_dir) return os.getcwd() def calculate_file_hash(file_path): sha256 = hashlib.sha256() with open(file_path, 'rb') as f: while chunk := f.read(4096): sha256.update(chunk) return sha256.hexdigest() async def result(): # 循环3次以得到24个哈希值(8*3) for i in range(3): await main() # 只遍历目录下的文件,跳过子目录 for f in os.listdir(): file_path = os.path.join(os.getcwd(), f) if os.path.isfile(file_path): print(calculate_file_hash(file_path)) # 返回初始目录,避免路径混乱 os.chdir("../../..") asyncio.run(result())
内容的提问来源于stack exchange,提问作者micro_chelik
相关产品推荐
相关产品推荐

