"""Streaming file hashing (stdlib only).""" import hashlib import zlib CHUNK = 1 << 23 # 8 MiB read chunks class HashCancelled(Exception): """Raised when hashing is cancelled mid-read.""" def hash_file(path, cancel=None): crc = 0 md5 = hashlib.md5() sha1 = hashlib.sha1() with open(path, "rb") as f: while True: if cancel is not None and cancel.is_set(): raise HashCancelled() block = f.read(CHUNK) if not block: break crc = zlib.crc32(block, crc) md5.update(block) sha1.update(block) return { "crc32": f"{crc & 0xFFFFFFFF:08X}", "md5": md5.hexdigest().upper(), "sha1": sha1.hexdigest().upper(), }