Digital Logic Toolkit — Parity & checksum
Parity and Checksum Calculator
From one parity bit to a CRC — six ways to detect a corrupted message, with the working for each and an honest statement of what each one misses.
Data
Read as bits: 7 bits · not a whole number of bytes — 1 short of 1 bytes
- bytes: 0
- bits: 7
Even parity bit
0
4 one bits in the data
Odd parity bit
1
Codeword, parity appended
10110010
Codeword, parity prepended
01011001
Even parity of 7 bits
Data1011001
Ones in the data4— even weight
Even parity: choose the bit that makes the total number of 1s even, so the parity bit equals the XOR of all data bits.
p (even)0— total ones becomes 4
Codeword (parity appended)10110010
Codeword (parity prepended)01011001
A single parity bit detects every odd number of bit errors and is blind to every even number. It can never correct anything: d_min = 2.
Source: R. W. Hamming, Bell System Technical Journal 29(2):147–160 (1950)
Why there are six of these and not one
Each rung detects something the one before it misses. A single parity bit misses every even number of flipped bits. A plain sum misses a reordering, because addition is commutative. The Internet checksum adds an end-around carry so a lost carry cannot hide. Fletcher adds a running total of the running total, which is what makes it order-sensitive. Luhn is position-weighted over decimal digits. A CRC is polynomial division, and it is the only rung with a stated burst-detection guarantee.
Notation used on this page
- Bytes are written most significant bit first, and a hex digit pair is one byte.
- A checksum is a detection code only: nothing on this page can correct anything. Correction needs the Hamming page.
- The Internet checksum is the one’s-complement sum of 16-bit words, complemented; a receiver summing the data with the checksum in place gets 0xFFFF.
Start from a worked example
The ladder
Everything on this page answers one question — has this message changed? — and the six methods form a ladder in which each rung exists because of something the rung below it misses. Every rung costs redundancy, which is information you add on purpose; the entropy calculator measures the same quantity from the other direction.
| Rung | What it adds over the rung before |
|---|---|
| 1 · Parity bit | Catches any odd number of flipped bits, and misses every even number. |
| 2 · Modular sum | Catches a changed value, and misses a reordering, because addition commutes. |
| 3 · One's-complement sum | Adds the carry back in, so a carry out of the top cannot hide a change. |
| 4 · Internet checksum | The one’s-complement sum, complemented, so verification is a single constant. |
| 5 · Fletcher | Adds a running total of the running total, which makes it order-sensitive. |
| 6 · CRC | Polynomial division: the only rung with a stated burst-detection guarantee. |
Parity bits
An even parity bit is chosen so the total number of ones in the word, the parity bit included, is even — which makes it exactly the XOR of all the data bits. An odd parity bit is its complement. For 1011001 there are four ones, an even count already, so the even parity bit is 0 and the odd parity bit is 1.
The empty word is a legal input, not an error: it has zero ones, which is even, so its even parity bit is 0 and its odd parity bit is 1. On placement: this page appends the parity bit on the least significant side unless the prepend control says otherwise, and it always says which it did — a codeword is not defined until the position is.
What a parity bit detects
Flip any one bit of a parity-protected word and the count changes from even to odd: detected. Flip any two and it is even again: undetected. Sweeping every error pattern over a word shows the same shape at every length — every odd-weight error is caught, every even-weight error is missed — and that is d_min = 2, a code that detects one error and corrects none.
A parity bit tells you that something is wrong. It never tells you what. For that you need a code that can correct, not just detect.
Where the eighth bit went
ASCII is a 7-bit code and a byte is 8 bits, and the gap is not an accident: the eighth bit was the parity bit. Serial links carried seven data bits plus one parity bit in an eight-bit frame, which is why the binary to text converter offers a true 7-bit mode alongside the 8-bit one. Modern links moved the check to the frame level and the eighth bit became data, which is what made Latin-1 and then UTF-8 possible.
Two-dimensional parity
Arrange the data as a rectangle, add a parity bit to every row and every column, and add one more in the corner. The corner bit is a self-check: the parity of the row parities equals the parity of the column parities, so if the two disagree the corner itself is damaged.
- One flipped bit fails exactly one row and one column, so it is located, and can be corrected.
- Two flipped bits fail two rows or two columns and are detected but not located.
- Four bits at the corners of a rectangle flip two rows and two columns twice each, so every check passes and the error is invisible. That is the blind spot, and it is why d_min is 4 rather than larger.
Two-dimensional parity locates a single error using 2√N extra bits. A Hamming code does the same job with about log₂N, which is the step this page’s ladder does not take.
Simple sums, and the three things called "the checksum"
Say which convention you mean. A modular sum, a two’s-complement checksum and a one’s-complement checksum of the same data are three different bytes.
| Called | Definition |
|---|---|
| Modular sum | Add the bytes and keep the low 8 bits. |
| Two's-complement checksum | The modular sum negated, so data plus checksum sums to 0. |
| One's-complement checksum | The end-around-carry sum complemented, so data plus checksum sums to all ones. |
| XOR-8 (BCC) | XOR every byte: a longitudinal parity byte, one parity bit per bit position. |
Each has its own verification identity, and they are not interchangeable. With a two’s-complement checksum appended, re-summing the whole message gives 0; with a one’s-complement checksum it gives all ones. A receiver that applies the wrong identity rejects every valid message.
The one's-complement sum and the end-around carry
Add the 16-bit words as ordinary integers and, whenever the sum exceeds 16 bits, add the carry back into the low end. Folding the carry back is what stops information escaping out of the top of the accumulator, and it makes the sum independent of the order the words are added in.
This is the same end-around carry as one’s-complement subtraction on the two’s complement page — the same mechanism, reached from the other direction.
The Internet checksum (RFC 1071)
RFC 1071 defines generation as: take the one’s-complement sum of the 16-bit words with the checksum field set to zero, then complement it. Verification is: take the one’s-complement sum of everything including the checksum field and check that the answer is all ones.
- Odd-length data is padded with a zero byte on the right, for the computation only.
- The sum is byte-order independent: swapping the bytes of every word rotates the sum by exactly eight bits, so a big-endian and a little-endian host agree on the transmitted value.
- A computed sum of
0xDDF2complements to0x220D, and quoting the sum where the checksum belongs is the classic transcription error. This page prints the sum and the checksum on two separately labelled rows for that reason.
Incremental update and the two zeros
A router that decrements a time-to-live field does not recompute the whole checksum; RFC 1624 gives the arithmetic for adjusting it. Its equation 2 can produce 0xFFFF where a full recomputation produces 0x0000— the two representations of zero in one’s-complement arithmetic — which is why RFC 1624 exists at all.
UDP resolves the ambiguity by convention: a transmitted checksum of 0x0000means “no checksum computed”, so a real result of zero is sent as 0xFFFFinstead. That rule is RFC 768’s.
Fletcher and Adler
Fletcher keeps two accumulators: sum1 adds each byte, sum2 adds sum1 after every byte. Because sum2 weights each byte by how many bytes follow it, reordering the message changes the result — the specific weakness a plain sum has. Fletcher-16 reduces both accumulators modulo 255 rather than 256, so that no byte value maps to zero and a run of zeros is not invisible.
Adler-32 is the same construction with the prime modulus 65521, which spreads the accumulator values more evenly at the cost of being weaker on very short messages. Its published check value over "123456789" is 0x091E01DE.
Luhn
Luhn is a decimal check digit, not a binary checksum. Starting from the rightmost digit and moving left, double every second digit and subtract 9 from any result above 9; the number is valid when the total is a multiple of 10. The check digit that completes a payload is the amount needed to reach the next multiple of 10.
It catches every single-digit error and almost every transposition of adjacent digits — except 09 ↔ 90, which doubles to the same total either way. That blind spot is documented in the standard rather than being a surprise. Spaces and hyphens are stripped before the digits are read, and this page says when it stripped them.
CRC
A CRC treats the message as a polynomial over GF(2) and takes its remainder modulo a generator polynomial. Division over GF(2) has no borrows: every subtraction is an XOR, which is why the long division can be done by hand and why the hardware is a shift register with a few XOR taps.
A CRC is defined by eight parameters, not by its polynomial.The RevEng catalogue’s model is width, polynomial, initial register value, input reflection, output reflection, final XOR, and the published check and residue values that let an implementation prove itself. Two implementations of “CRC-16” with the same polynomial and different reflection settings produce different answers, and both are correct for their own model.
Append the CRC little-endian when refout is true and big-endian otherwise; the residue only reproduces if you get this right. Running the algorithm over the message with its CRC appended gives the model’s residue constant, which is the cheapest end-to-end check that an implementation is correct.
Detect versus correct
Everything on this page detects. Nothing on this page corrects. Correction needs the redundancy to be placed so that the failing checks identify a position, which is what the Hamming code does and what no checksum here attempts.
Notation used on this page
- Bits are written most significant first.
- The parity bit is appended on the least significant side unless the prepend control says otherwise.
- Bytes are paired into 16-bit words big-endian for the Internet checksum, and odd-length data is zero-padded on the right for the computation only.
~is bitwise complement and⊕is XOR.- The one’s-complement sum and the checksum are separate labelled rows and are never the same number.
- CRC polynomials are written in direct MSB-first notation with the implicit x^width term omitted; hexadecimal is upper case with a
0xprefix.
Sources
- RFC 1071 — Computing the Internet Checksum (opens in a new tab): generation, verification and the byte-order property.
- RFC 1624 — Computation of the Internet Checksum via Incremental Update (opens in a new tab): the update equations and the two zeros.
- RFC 768 — User Datagram Protocol (opens in a new tab): the
0x0000→0xFFFFrule only. - The RevEng CRC catalogue and its legend (opens in a new tab): the eight-parameter model and every preset in the table.
- ISO/IEC 7812-1, Annex B: the Luhn check-digit algorithm.
- R. W. Hamming, “Error Detecting and Error Correcting Codes” (opens in a new tab), 1950 — cited once above, as the pointer to correction.
Worked examples
- Even parity bit for 1011001intromake the total number of 1s even
- Odd parity bit for 1011001introthe opposite convention
- Parity cannot detect two errorscorethe fundamental limitation
- 2D parity over a 4×4 blockcoreparity in two directions corrects
- One's-complement sum of 0x1234 and 0xABCDcoreend-around carry
- Internet checksum of a short headerexamone's-complement sum, then complement
- XOR checksum of four bytesexamthe weakest useful checksum
- CRC-8 versus a simple checksumedge casewhy real protocols use CRC