Error Correction

Parity Check Bit

One extra bit, all odd errors caught — the simplest detection trick still in use

A parity bit appends one redundant bit per word so the count of 1s is always even (or always odd). Detects every single-bit flip; misses every double flip; corrects nothing.

  • Overhead1 bit per word (12.5% for a byte)
  • DetectsAll odd-count errors
  • MissesAll even-count errors
  • CorrectsNothing (detection only)
  • VariantsEven, odd, mark, space
  • Used inUART, RAID-3, PCIe, SCSI

Interactive visualization

Press play, or step through manually. The visualization is yours to drive — try it before reading on.

Open visualization fullscreen ↗

Watch the 60-second explainer

A condensed visual walkthrough — narrated, captioned, under a minute.

How a parity bit works

One sentence: append a bit chosen so the total count of 1s in the word is even (even parity) or odd (odd parity). Sender and receiver agree on the convention beforehand. The receiver counts the 1s in every word. Even parity, even count: OK. Even parity, odd count: at least one bit flipped in flight.

That single bit detects every single-bit error and every error involving an odd number of flips. It misses every error involving an even number of flips — two flips swap the count by 0 (net), three flips by an odd offset, and so on. Parity is the simplest member of the family of linear block codes and the entire reason richer schemes like Hamming exist.

data byte    : 0 1 1 0 1 1 0 1     ← five 1s
parity bit   :                  1   ← chosen to make total even
transmitted  : 0 1 1 0 1 1 0 1 1    ← six 1s, even ✓

…in transit, bit 3 flips…

received     : 0 1 1 1 1 1 0 1 1    ← seven 1s, odd ✗ — error!

The receiver sees odd count, raises an error flag, asks for retransmission, drops the byte, or whatever the protocol layer specifies. It cannot say which bit flipped — only that one (or three, or …) did.

Worked example — UART 8E1

A serial UART transmitting "8E1" means 8 data bits, even parity, 1 stop bit — 11 bits per byte on the wire (start + 8 + parity + stop). Take the ASCII letter 'A' = 0x41 = 01000001. Two 1s → already even → parity bit is 0. The receiver clocks in 11 bits, counts 1s in bits 1-9, expects even. If a noise pulse flips bit 4 from 0 to 1, the count becomes 3 → odd → framing error raised.

RS-232 has carried parity in its DNA since 1960. Modern UARTs still implement it; embedded firmware regularly uses 9E1 or 8O1 when talking to legacy industrial equipment.

What parity costs (and misses)

  • 1 bit per word. 12.5% overhead for a byte; 3.1% for a 32-bit word; 1.5% for a 64-bit word. The overhead drops as the word grows, but so does protection — one parity bit can't distinguish 1 flip from 3 within a 64-bit word.
  • Detects 100% of single-bit errors within the protected unit.
  • Misses 100% of two-bit errors. Two flips XOR to zero in the count.
  • Detects 50% of multi-bit random errors as the number of flips approaches infinity. The miss probability approaches 50% (the chance of even-count flips in a random scrambling) — barely better than a coin flip against burst noise.
  • Zero correction. If the protocol can't retransmit, a parity-failed word is simply lost.

Parity vs ECC vs CRC vs Reed-Solomon

Parity bitHamming SEC-DEDCRC-32Reed-SolomonLDPCNone
DetectsOdd-count1 or 2 flipsAll bursts ≤32 bitst/2 symbolsMost burstsNothing
CorrectsNone1 flipNone (typically)t/2 symbolsHeavy redundancyNone
Overhead~1.5-12.5%~12.5%32 bits per frame~20-50%~50-100%0%
ComputeOne XORXOR treeShift-register / tableGalois field mathIterative decoder
Used inUART, RAID-3DRAM, cachesEthernet, ZIP, TCPCDs, DVDs, QR, RAID-65G, WiFi-6, SSDsThrowaway data
Hardware costTrivialCheapModerateHeavyVery heavyNone

The right code depends on the error model. Random single-bit flips → parity or Hamming. Burst errors on a wire → CRC. Symbol-level corruption from a scratched disc → Reed-Solomon. Modern wireless channels → LDPC.

Parity in RAID — the erasure trick

RAID-3 (and the more popular RAID-5) stripe data across N drives and dedicate one drive to parity: byte 0 of the parity drive is the XOR of byte 0 of every data drive. If any single drive fails — the array knows which one — the missing data is reconstructed by XOR'ing the remaining drives.

This works because a known erasure is easier than an unknown error. The system already knows which drive is gone (the controller reports it), so it only needs to recover the values, not locate them. One parity bit per stripe suffices for any single-drive recovery; RAID-6 adds a second parity (Reed-Solomon based) for two-drive tolerance.

Stripe across 4 data drives + 1 parity drive:
  d0 = 0x4A   d1 = 0xC3   d2 = 0x1F   d3 = 0x82   p = d0^d1^d2^d3 = 0x16

Drive d2 dies. Reconstruct:
  d2 = d0 ^ d1 ^ d3 ^ p = 0x4A ^ 0xC3 ^ 0x82 ^ 0x16 = 0x1F ✓

Parity in JavaScript

// Even parity: count 1s, append 1 bit so total is even
function appendEvenParity(byte) {
  let ones = 0;
  for (let i = 0; i < 8; i++) if (byte & (1 << i)) ones++;
  const parity = ones & 1;     // 1 if odd → flip to make even
  return (byte << 1) | parity; // 9-bit result
}

function verifyEvenParity(ninebit) {
  let ones = 0;
  for (let i = 0; i < 9; i++) if (ninebit & (1 << i)) ones++;
  return (ones & 1) === 0;     // even = pass
}

// XOR-folded version (no loop) — what hardware actually does
function parityXor(byte) {
  let x = byte;
  x ^= x >> 4;
  x ^= x >> 2;
  x ^= x >> 1;
  return x & 1;
}

// RAID-3 reconstruction
function reconstructStripe(drives, missingIdx) {
  const recovered = drives.reduce((acc, d, i) =>
    i === missingIdx ? acc : acc.map((b, j) => b ^ d[j]),
    drives[missingIdx].map(() => 0));
  return recovered;
}

The XOR fold version is what every CPU and FPGA implements — five gates wide, one clock cycle deep. Real hardware never loops to compute parity.

Parity in Python

def even_parity(word: int, width: int = 8) -> int:
    """Return word with one parity bit appended (LSB)."""
    bits = bin(word).count('1')
    return (word << 1) | (bits & 1)

def verify_parity(word_with_parity: int, width: int = 9) -> bool:
    return bin(word_with_parity).count('1') % 2 == 0

# UART-style stream check
def decode_serial(bits: list[int], parity: str = 'even') -> int | None:
    data = sum(b << i for i, b in enumerate(bits[:8]))
    received_parity = bits[8]
    expected = bin(data).count('1') & 1
    if parity == 'even' and received_parity != expected: return None
    if parity == 'odd'  and received_parity == expected: return None
    return data

# RAID-3 stripe parity
def raid3_parity(stripes: list[bytes]) -> bytes:
    """XOR all stripes together. Result has same length as one stripe."""
    width = len(stripes[0])
    return bytes(
        eval('^'.join(str(s[i]) for s in stripes))
        for i in range(width)
    )

Variants — block, longitudinal, vertical

Simple parity (1D). One bit per byte or word. UARTs, parity DRAM, SCSI.

Longitudinal redundancy check (LRC). Compute parity column-wise across a block of bytes — each bit position gets its own parity bit. Detects burst errors that single parity misses. Used in old magnetic tape formats.

2D parity (rectangular code). Arrange data as a grid; add parity bit per row AND per column. Single-bit errors are uniquely locatable (row and column parity intersect). 2× overhead. Forerunner of the Hamming code.

Mark and space parity. The parity bit is always 1 (mark) or always 0 (space), regardless of data. Useless for detection — used historically as a 9th bit signaling channel for legacy multidrop protocols.

Cross-interleaved Reed-Solomon (CIRC). Audio CDs interleave two layers of Reed-Solomon parity. Survives 4mm scratches. The descendant of parity that ate the music industry.

When parity is enough

  • Low-error channels where loss is tolerable. A serial debug console can drop a byte; the user retypes the command.
  • Erasure recovery (RAID). When the system knows which word is missing, one parity bit recovers it.
  • Cheap sanity checking inside SoCs. AXI bus lanes, PCIe link layer, internal cache tags. The expected error rate is single-bit and bursts are caught by upstream codes.
  • Building block in larger codes. The "overall parity" bit in Hamming SEC-DED is exactly this. CRCs reduce to a polynomial parity. Every modern code descends from parity.

For anything that retains state across hours or days — disk drives, DRAM, flash — parity alone is too weak. The asymmetry of error costs (silent corruption is far worse than visible failure) drives those domains to ECC or stronger.

Common parity bugs

  • Even/odd mismatch. Sender configured for "even", receiver for "odd": every byte fails. Classic UART bring-up bug.
  • Missing the parity bit in framing. A serial driver that counts data bits but ignores parity bit position misaligns the stream after the first parity error.
  • Burst errors fooling parity. Lightning, motor noise, or interference flip many bits at once. Half the time the count stays even and parity reports no error. Use CRC for burst-prone channels.
  • Parity bit corruption itself. A flip in the parity bit alone reports "error" while the data is intact. Detection-only parity can't distinguish; protocols typically retransmit on any failure.
  • Confusing parity drives with mirrors. RAID-3/5 parity recovers one drive; mirrors (RAID-1) recover from drive loss by reading the copy. Different fault models, different overheads.
  • Stuck-at-1 line giving "always odd." A hardware short can hold a bit high; with odd parity, this passes; with even parity, it always fails. Some test rigs use both schemes to catch stuck lines.

Frequently asked questions

Even or odd parity — does it matter which?

Either works for detection. Even parity is more common — the parity bit makes the total count of 1s even. Odd parity has a tiny robustness advantage: a fully-zero word (a stuck line at 0) fails the parity check, so a totally broken channel is detected. Both schemes share identical error-detection power.

Can a parity bit ever correct an error?

No. Parity tells you that one bit (or three, or five) flipped, but not which one. Correction requires more redundancy — at minimum, the Hamming SEC code with ceil(log2(n+1)) check bits for n data bits. Pure parity is detection-only.

What's the overhead of a single parity bit?

Depends on the data unit. Per-byte parity is 1 bit per 8 = 12.5% overhead (the classic '9th bit' on parity DRAM, serial UART, and old SCSI). Per-word parity at 32 or 64 bits drops overhead to 1.5% or 3%. RAID-3 distributes one parity drive across N data drives — overhead 1/N.

Why is parity used in RAID but not modern memory?

RAID parity catches drive failures (a missing drive is a known erasure — parity reconstructs it). Memory faces unknown bit positions, where parity can detect but not locate. Modern memory uses ECC (Hamming SEC-DED) for that reason; modern RAID is striped parity (RAID-5/6) or full erasure codes.

Does parity work for multi-bit errors?

It detects all odd-count errors (1, 3, 5, … bits flipped). It misses all even-count errors (2, 4, …) because two flips cancel out in the count. The miss probability of multi-bit errors approaches 50% as flip count grows — useless against bursty noise where many bits flip together.

Where do I see parity in practice today?

Serial UART '8N1' vs '8E1' configurations, RS-232 legacy hardware, retro DRAM (FastPage parity 30-pin SIMMs), SCSI cabling, PCIe lane integrity bits, AXI buses inside SoCs, and as the overall parity bit in every Hamming SEC-DED code. The simplest tool is still the most ubiquitous building block.