31 lines
768 B
Python
31 lines
768 B
Python
"""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(),
|
|
}
|