Checksums in System Design: CRC, MD5, SHA and How Data Integrity Works (Visualized)
A checksum is a small value computed from a block of data that lets receivers verify whether the data arrived intact. From TCP segments to file downloads to disk storage, checksums are the first line of defence against silent data corruption โ and this guide explains exactly how they work.
A checksum is a small fixed-size value derived from a block of data that lets a receiver verify whether the data arrived without accidental corruption. Think of it as a fingerprint: if even one bit changes in transit, the fingerprint changes too, and the mismatch flags the error immediately.
Checksums appear everywhere in computing: inside every TCP segment, on every disk sector, in every downloaded file, and across every distributed database replication stream. They are cheap to compute, cheap to compare, and provide a strong probabilistic guarantee that what you received is exactly what was sent. Understanding checksums is fundamental to reasoning about reliability in any system that moves or stores data.
How Checksums Work: Send, Receive, Compare
The protocol is always the same three-step dance. Step 1 โ Sender: compute the checksum over the data (e.g. sum all bytes mod 256, or run a CRC polynomial), then attach it to the message. Step 2 โ Channel: the data travels over a network, disk, or any other medium that might introduce noise. Step 3 โ Receiver: recompute the checksum from the received data and compare it with the attached value. If they match, the data is almost certainly intact. If they differ, corruption has occurred and the receiver can request a retransmission or discard the data.
A critical point: checksums detect corruption but do not correct it. When a mismatch is found, the receiver knows something went wrong, but cannot reconstruct the original data. The response is typically to discard the data and ask for a retransmission (as TCP does) or to return an error to the application layer. Error-correcting codes (like Reed-Solomon or Hamming codes) go further and can recover the original bits, but they carry more overhead.
Bit Flips: How a Single Change Breaks the Checksum
In the real world, corruption usually manifests as a bit flip โ a 0 becomes a 1, or vice versa โ caused by electrical noise, cosmic rays, failing memory cells, or signal degradation on a wire. Even one flipped bit produces a completely different checksum value when the receiver recomputes it, which is the key property that makes checksums useful. The animation below shows exactly this scenario.
The probability that a checksum fails to detect corruption depends on how many bits the checksum contains. A 16-bit checksum misses a random error with probability 1/65,536 (about 0.0015%). A 32-bit CRC misses a random error with probability roughly 1 in 4 billion. Cryptographic hashes like SHA-256 make collisions computationally infeasible, though they are far more expensive to compute than a simple CRC.
Types of Checksums: Simple Sum, CRC, and Cryptographic Hashes
Not all checksums are equal. They sit on a spectrum from ultra-fast but weak to cryptographically strong but expensive.
Simple additive checksum: sum all bytes and keep the low N bits. Used in IPv4 headers. Fast and trivial to compute in hardware, but cannot detect transposed bytes (0xAB 0xCD and 0xCD 0xAB produce the same sum). A classic example in Python: sum(data) & 0xFF.
Cyclic Redundancy Check (CRC): treats the data as a large binary polynomial and divides it by a fixed generator polynomial, keeping the remainder. CRC-32 (used in Ethernet, ZIP, and PNG) detects all single-bit errors, all two-bit errors in a frame, all odd numbers of errors, and all burst errors up to 32 bits long โ making it vastly superior to additive checksums for communication channels.
Cryptographic hash functions (MD5, SHA-1, SHA-256): designed so that finding two different inputs with the same output is computationally infeasible. They are too slow for per-packet use in networking hardware, but ideal for file integrity checks, software distribution, and digital signatures. Note that MD5 and SHA-1 are cryptographically broken โ an attacker can craft collisions. For security-sensitive uses, prefer SHA-256 or SHA-3.
import hashlib
import zlib
data = b'Hello, distributed system!'
# Simple additive checksum (weak)
simple_ck = sum(data) & 0xFFFF
print(f'Simple checksum : 0x{simple_ck:04X}')
# CRC-32 (good for data integrity over channels)
crc32 = zlib.crc32(data) & 0xFFFFFFFF
print(f'CRC-32 : 0x{crc32:08X}')
# MD5 (fast, but cryptographically broken)
md5 = hashlib.md5(data).hexdigest()
print(f'MD5 : {md5}')
# SHA-256 (recommended for security-sensitive uses)
sha256 = hashlib.sha256(data).hexdigest()
print(f'SHA-256 : {sha256}')| Method | Output Size | Speed | Detects Tampering? | Typical Use |
|---|---|---|---|---|
| Additive Sum | 8โ16 bits | Fastest | No (easy to forge) | IPv4 header, UDP |
| CRC-32 | 32 bits | Very fast (hardware) | No (easy to forge) | Ethernet, ZIP, PNG, TCP |
| MD5 | 128 bits | Fast (software) | Broken (collisions known) | Legacy file checksums |
| SHA-1 | 160 bits | Moderate | Broken (collisions known) | Legacy VCS (old Git) |
| SHA-256 | 256 bits | Moderate | Yes (computationally safe) | File downloads, TLS, Git (new) |
| SHA-3 / Blake3 | 256+ bits | Fast (Blake3) | Yes | Modern security, storage |
Checksums in TCP/IP, Storage, and File Downloads
TCP/IP: Every TCP segment carries a 16-bit checksum over the header and payload. The OS computes it before sending and verifies it on receipt โ corrupted segments are silently dropped and TCP's retransmission mechanism handles recovery. Ethernet frames add a separate CRC-32 at layer 2. This two-layer protection means most hardware-level corruption never reaches the application.
Disk storage: Modern file systems (ZFS, Btrfs, APFS) store a checksum alongside every data block. When a block is read, the checksum is recomputed. If it does not match, the file system knows the block is corrupt โ and if RAID or replication is present, it can transparently repair the block from a good copy. Hard disks and SSDs also use internal ECC (Error Correcting Codes) at the sector level, which can fix small errors without involving the OS.
File downloads: When you download software, the publisher typically provides a SHA-256 hash alongside the download link. After downloading, you run sha256sum file.iso and compare the output to the published value. A match means the file is identical to what the publisher released โ no bytes were lost in transit and, crucially for security, no attacker injected malicious bytes into the file.
Detect vs Correct: Checksums vs Error-Correcting Codes
Checksums sit in the error-detection category. An error-correcting code (ECC) stores enough redundancy to locate and repair flipped bits without a retransmission. Hamming codes can correct one-bit errors in a data word. Reed-Solomon codes (used in QR codes, CDs, and deep-space communication) can recover data even when a large burst of bytes is entirely lost. The trade-off is overhead: a CRC-32 adds just 4 bytes to any message; Reed-Solomon might add 30โ50% redundancy. Choose detection when retransmission is cheap; choose correction when it is impossible or too expensive.
In practice, modern systems layer both mechanisms. A hard disk uses internal ECC to silently fix one-bit errors in a sector, while the file system's block-level checksum catches anything the ECC cannot fix. TCP uses a 16-bit checksum to detect errors the Ethernet CRC missed. Each layer provides defence-in-depth against the modes of failure that slip past the layer below.
Checksums in Distributed Systems
In distributed systems, checksums play an additional role beyond channel integrity: they verify that replicated data is consistent across nodes. Apache Cassandra uses MD5 checksums in its Merkle tree anti-entropy repair to compare rows between replicas โ any subtree whose hash differs indicates diverged data, which is then reconciled. Amazon S3 returns an ETag (MD5 or SHA-256) for every object; clients can verify downloads byte-for-byte. Git uses SHA-1 (now migrating to SHA-256) to address every object by its content hash, making the entire repository history tamper-evident by construction.
A common pattern in distributed pipelines is the end-to-end checksum: compute a hash of a payload at the producer, persist it alongside the data, and re-verify at every consumer. This catches not just in-flight corruption but also at-rest corruption (a bit rot on a disk), misconfigured serialisation, or logic bugs that silently mutate data. It is cheap insurance against a class of bugs that is otherwise extremely hard to debug in production.
Frequently Asked Questions
What is the difference between a checksum and a hash?
All checksums are hashes, but not all hashes are checksums. In common usage, checksum usually refers to a simple, fast value (additive sum or CRC) optimised for detecting accidental errors in a communication channel. Hash function is the broader category and includes cryptographic hashes like SHA-256, which are additionally designed to resist intentional forgery. For data integrity in networking and storage use CRC; for security-sensitive verification (file authenticity, digital signatures) use a cryptographic hash such as SHA-256.
Can a checksum guarantee data is correct?
No โ checksums provide a probabilistic guarantee, not a certainty. It is possible (though unlikely) for two different byte sequences to produce the same checksum, a situation called a collision. For a CRC-32 the probability of an undetected random error is about 1 in 4.3 billion. For SHA-256 the collision probability is so astronomically small (roughly 1 in 2^256) that it is treated as impossible in practice. However, checksums cannot detect corruption that happens to land in a pattern that preserves the checksum value, and they cannot detect an attacker who recomputes the checksum over the malicious data unless a keyed MAC (HMAC) is used instead.
Why does TCP have a checksum if Ethernet already has CRC?
Ethernet's CRC-32 protects a frame only while it travels on a single physical link. At each router hop, the Ethernet frame is stripped and rebuilt, so the CRC is verified and removed at every hop โ it does not survive end-to-end. The TCP checksum, by contrast, is computed end-to-end by the sender's OS and verified by the receiver's OS, covering the segment as it passes through the entire network path including any routers that might introduce corruption in their internal memory or buses. This is an instance of the end-to-end argument: if you want a guarantee across the full path, enforce it at the endpoints.
A checksum is the cheapest form of trust you can add to a system: a few bytes computed at the source and verified at the destination that silently protect every byte in between.
โ alokknight Engineering
