How to Compare Two Files by Content Hash Equality in Python

Compares two files by hashing their contents with SHA-256, skipping the hash if file sizes differ, and returns whether they are identical.

Medium Python 3.9+ Aug 9, 2026 Files & data 14 views 0 copies

Python code

22 lines
Python 3.9+
import hashlib
from pathlib import Path

def file_hash(path: Path, chunk_size: int = 8192) -> str:
    sha256 = hashlib.sha256()
    with path.open("rb") as f:
        for chunk in iter(lambda: f.read(chunk_size), b""):
            sha256.update(chunk)
    return sha256.hexdigest()

def files_are_identical(file_a: Path, file_b: Path) -> bool:
    if not file_a.exists() or not file_b.exists():
        return False
    if file_a.stat().st_size != file_b.stat().st_size:
        return False
    return file_hash(file_a) == file_hash(file_b)

if __name__ == "__main__":
    a = Path("file1.txt")
    b = Path("file2.txt")
    identical = files_are_identical(a, b)
    print(f"Files identical: {identical}")

Output

stdout
Files identical: True

How it works

The file_hash function reads files in fixed-size chunks using iter(lambda: f.read(chunk_size), b"") to avoid loading large files into memory, updating a SHA-256 digest incrementally. files_are_identical first checks both files exist and have equal sizes — a cheap early exit that prevents needless hashing when sizes differ. The final comparison hashes both files and compares the hex digests, which is fast and memory-efficient even for large files. This approach works because SHA-256 has an extremely low collision probability, making it a reliable content equality check.

Common mistakes

  • Forgetting to open files in binary mode ('rb'), causing encoding errors
  • Reading entire files with .read() instead of chunking, which consumes huge memory
  • Skipping the size check and hashing files even when sizes differ, wasting resources
  • Not verifying file existence first, leading to confusing FileNotFoundError traces

Variations

  1. Use `hashlib.md5()` for faster hashing when files are small and collision risk is acceptable
  2. Use `filecmp.cmp(file_a, file_b, shallow=False)` for a simple stdlib alternative without explicit hashing

Real-world use cases

  • Verifying that a downloaded file matches a checksum provided by the server to detect corruption.
  • Detecting duplicate files across storage directories without relying on filename comparisons.
  • Confirming a config or asset file was not altered during a deploy or sync job.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Files & data

Related tutorials and quizzes for this topic.