File Hashing and Integrity Verification with Python
Hashing lets you verify that a file hasn't been modified or corrupted. Python's hashlib module supports MD5, SHA-1, SHA-256, SHA-512, and many other algorithms.
Calculate a File Hash
import hashlib
def hash_file(path, algorithm="sha256"):
h = hashlib.new(algorithm)
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
h.update(chunk)
return h.hexdigest()
path = "document.pdf"
print(f"MD5: {hash_file(path, 'md5')}")
print(f"SHA1: {hash_file(path, 'sha1')}")
print(f"SHA256: {hash_file(path, 'sha256')}")
print(f"SHA512: {hash_file(path, 'sha512')}")
Verify File Integrity
import hashlib
def verify_file(path, expected_hash, algorithm="sha256"):
h = hashlib.new(algorithm)
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
h.update(chunk)
actual = h.hexdigest()
ok = actual.lower() == expected_hash.lower()
status = "OK" if ok else "CORRUPTED"
print(f"[{status}] {path}")
if not ok:
print(f" Expected: {expected_hash}")
print(f" Actual: {actual}")
return ok
# SHA256 published by the developer
official_hash = "a3f5c2e1d8b4f9e0c7a2b6d3e5f8a1b4c9d2e7f0a5b8c3d6e9f2a5b8c3d6e9f2"
verify_file("installer.exe", official_hash)
Generate a Checksums File (like sha256sum)
import hashlib
from pathlib import Path
def generate_checksums(folder, algorithm="sha256", output="checksums.txt"):
files = sorted(Path(folder).rglob("*"))
lines = []
for path in files:
if not path.is_file(): continue
h = hashlib.new(algorithm)
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
h.update(chunk)
rel = path.relative_to(folder)
lines.append(f"{h.hexdigest()} {rel}")
print(f" {rel}")
with open(output, "w") as f:
f.write("\n".join(lines))
print(f"\nGenerated {len(lines)} checksums in {output}")
generate_checksums("my_project/", output="sha256sums.txt")
Verify Directory Checksums
import hashlib
from pathlib import Path
def verify_checksums(checksums_file, base_dir="."):
errors = 0
with open(checksums_file) as f:
for line in f:
line = line.strip()
if not line: continue
expected, rel_path = line.split(" ", 1)
path = Path(base_dir) / rel_path
if not path.exists():
print(f"[MISSING] {rel_path}")
errors += 1
continue
h = hashlib.sha256()
with open(path, "rb") as fp:
for chunk in iter(lambda: fp.read(65536), b""):
h.update(chunk)
if h.hexdigest() == expected:
print(f"[OK] {rel_path}")
else:
print(f"[CORRUPTED] {rel_path}")
errors += 1
print(f"\nErrors found: {errors}")
return errors == 0
verify_checksums("sha256sums.txt", "my_project/")
Find Duplicate Files
import hashlib
from pathlib import Path
from collections import defaultdict
def find_duplicates(folder):
hashes = defaultdict(list)
for path in Path(folder).rglob("*"):
if not path.is_file(): continue
h = hashlib.md5()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
h.update(chunk)
hashes[h.hexdigest()].append(path)
dupes = {h: paths for h, paths in hashes.items() if len(paths) > 1}
if dupes:
print(f"Duplicate groups: {len(dupes)}")
for h, paths in dupes.items():
print(f"\n Hash: {h[:16]}...")
for p in paths:
print(f" {p}")
else:
print("No duplicates found")
return dupes
find_duplicates("my_photos/")
Hash Strings (Passwords, Tokens)
import hashlib, secrets
def hash_password(password: str) -> tuple[str, str]:
salt = secrets.token_hex(32)
h = hashlib.sha256((salt + password).encode()).hexdigest()
return salt, h
def verify_password(password: str, salt: str, stored_hash: str) -> bool:
h = hashlib.sha256((salt + password).encode()).hexdigest()
return h == stored_hash
salt, stored = hash_password("my_secret_password")
print(f"Salt: {salt}")
print(f"Hash: {stored}")
print(f"OK: {verify_password('my_secret_password', salt, stored)}")
Additional Resource
For converting and verifying files between different formats without any coding, use KaijuConverter — free and no registration required.
Related conversions
Frequent conversions across the catalogue: