Error Detection: Parity, Checksums and CRCs
Noise flips bits, so send a few extra bits computed from the data and let the receiver redo the computation. A parity bit catches any odd number of flips. A CRC treats the message as a polynomial and divides mod 2, and with check bits it catches every burst of errors up to bits long.
What the symbols mean
- Parity bit
Makes the total number of 1s even.
- XOR
Addition mod 2, so 1 ⊕ 1 = 0.
What the symbols mean
- Transmitted word
A multiple of G(x), so dividing it leaves remainder 0.
- Message
The data bits as polynomial coefficients.
- Remainder
The r check bits.
- Generator
A fixed polynomial of degree r that both ends agree on.
- The field {0, 1}
Arithmetic mod 2, where 1 + 1 = 0.
Explanation
An error-detecting code is simply a few extra bits, computed from your data and sent along with it, so the receiver can tell whether anything got damaged on the way. The names are literal: a parity bit records whether the count of 1s is even or odd (parity means evenness), a checksum is a sum used as a check, and CRC stands for cyclic redundancy check. They're what let a network card or a car's computer reject a garbled message instead of acting on it. The CRC formula looks heavy, but it's three pieces: (your message), (make room at the end for check bits) and (the check bits that fill that room), chosen so the whole thing divides evenly by an agreed . It looks complex, but it's just long division with bits; bear with it.
Noise, cosmic rays and loose connectors flip bits. The fix is redundancy: the receiver recomputes the extra bits from the data it got, and if its answer doesn't match the ones that came along, something got damaged on the way.
XOR is addition mod 2: , with no carry. An even parity bit is the XOR of all the data bits, so the total number of 1s comes out even. The receiver XORs everything it got and expects 0. One flipped bit makes the count odd, so it's caught. Two flips cancel, so they're missed. In general, parity catches exactly the errors with an odd number of flipped bits.
How often does parity miss? This is where probability comes in. If each of bits flips independently with probability , the number of flips is binomial. Adding the two expansions of and , with , cancels the odd terms and gives
Subtract the chance of no flips at all, , and what's left is the chance of an error parity can't see.
Checksums add up the bytes (mod 256, say) and send the sum. They catch more than one parity bit, but they're blind to bytes arriving in the wrong order, since addition is commutative.
CRCs: division mod 2. So what can we do that's stronger? The idea is the same as checking that a number is divisible by 9: if the sender makes the whole message a multiple of something, damage will almost always break that. Read a bit string as a polynomial with coefficients in : 1101 is . Adding is XOR, because . Sender and receiver agree on a generator of degree . The sender appends zeros (multiplying by ), divides by , and replaces the zeros with the remainder . Now the transmitted is a multiple of : subtracting the remainder from the dividend leaves a multiple, and subtracting is adding mod 2. The receiver divides by and expects remainder 0.
Write the damage as an error pattern , with 1s where bits flipped. The receiver sees , and since already divides , the error slips through only if divides too. That's what gives a CRC its guarantees:
- if has two or more terms, it never divides , so every single-bit error is caught;
- if divides , every odd number of errors is caught, because for those while ;
- if has a constant term, every burst of errors spanning at most bits is caught.
In hardware a CRC is just a shift register with a few XOR gates (a linear-feedback shift register), so it keeps up with the wire. Ethernet frames end in a 32-bit CRC, CAN buses in cars use a 15-bit CRC, and USB uses 5- and 16-bit ones. In software it's a loop of shifts and XORs:
uint8_t crc8(const uint8_t *data, int n) { // generator x^8 + x^2 + x + 1
uint8_t crc = 0;
for (int i = 0; i < n; i++) {
crc ^= data[i];
for (int k = 0; k < 8; k++) // one step of long division
crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : crc << 1;
}
return crc;
}
See it
Worked examples
Find the even-parity bit for 1011 0010. Then check a received byte 1011 0110 that arrived with parity bit 0.
- 1
1011 0010 has four 1s, already even, so the parity bit is 0.
Compute the 3-bit CRC of the message 1101 with generator (1011).
- 1
Append three zeros, which multiplies by : 1101000.
Practice
Type your answer and check it. Solve them all to complete the lesson.
Find the even-parity bit for the byte 1101 0111.
Which errors does a single even-parity bit always catch?
Over , adding polynomials is XOR of their bit strings. Add and , and give the result as a bit string with the prefix 0b.
Compute the 3-bit CRC of the message 1001 with generator (1011). Give the remainder with the prefix 0b.
A sensor sends 9-bit words (8 data bits plus a parity bit) over a noisy wire where each bit flips independently with probability . What's the probability that a word arrives with an error that parity doesn't catch?
Firmware files in Intel HEX format end each line with a checksum byte chosen so that all the bytes on the line add up to 0 mod 256: it's the two's complement of the sum of the others. A line holds the bytes 0x12, 0x7F and 0xC2. Which checksum byte goes at the end? Answer in hex.
CAN, the bus connecting a car's computers, protects each frame with a CRC of degree 15. A spark from the ignition flips 9 adjacent bits in one frame. Is the error guaranteed to be detected?
The hardest one here. Get it, and you've got this lesson.
A 4-bit CRC with generator (10011) protects the message 1101 0110. Find the 4 check bits, with the prefix 0b.
Where it's used
Every Ethernet frame ends in a 32-bit CRC, CAN buses in cars check every frame with a 15-bit CRC, and firmware files in Intel HEX format carry a checksum on every line, so a corrupted update gets rejected instead of bricking the device.