Encode and decode block codes (Hamming 7,4 / extended Hamming 8,4 / repetition / even-parity), see the G and H matrices, the minimum distance dmin, and the error-correction capability. Demo single-bit error correction with syndrome lookup. Compute CRC-4/8/CCITT/16 with the LFSR state trace. Run a (7,5) convolutional encoder + Viterbi decoder on a trellis, see the survivor paths. BER vs Eb/N0 for coded vs uncoded BPSK over AWGN.
⚠ Common confusion:Block code (Hamming, BCH, RS) operates on fixed-size blocks of k bits → n bits. Convolutional code is a sliding window — output depends on the last K input bits, no block boundary. The Viterbi decoder is the optimal decoder for convolutional codes.
① Block code (G, H, dmin, BER curves)
Pick a code from the left. The generator matrix G (k × n) maps a k-bit message to an n-bit codeword: c = m · G (mod 2). The parity-check matrix H ((n-k) × n) is used for decoding: the syndrome s = r · HT is zero iff the received codeword r is a valid codeword. The minimum distance dmin is the smallest Hamming weight of any non-zero codeword; the code can correct ⌊(dmin−1)/2⌋ errors and detect dmin−1.
BER vs Eb/N0 for coded (Hamming 7,4) vs uncoded BPSK over AWGN (hard-decision). Coding gain: at BER = 10−3, the coded curve sits ≈ 2-3 dB to the left of uncoded. Below the code's error-correction threshold, coding helps; above it, the curves converge (we're running at the channel capacity limit).
Uncoded BPSK (theory: Q(√(2·Eb/N0))) Coded BPSK (Monte-Carlo sim with hard-decision Viterbi for the convolutional code, syndrome for the block code) current Eb/N0
② Hamming demo (encode, flip a bit, decode)
Type a 4-bit message; pick a bit position to flip (0-6) or -1 for no error. The page shows the original codeword, the received codeword (with the flipped bit highlighted), the syndrome, the syndrome lookup table, and the corrected codeword. The KV panel reports whether the decode was successful.
Syndrome → error-position lookup table (Hamming(7,4) only). The position is the bit index to flip in the received codeword. Syndrome 000 = no error detected.
③ CRC (polynomial division via LFSR)
Type a bit-string and pick a polynomial. The LFSR shifts each input bit through, XORing with the polynomial when the MSB is 1. The final LFSR state (after K extra shifts) is the CRC. This is the bit-by-bit implementation; for production code, use a 256-entry lookup table. CRC detects all single-bit errors, all double-bit errors, and all burst errors up to the polynomial's degree.
LFSR state after each step (left = MSB = xK, right = x0). Highlighted cells are the active XOR feedback taps.
④ Convolutional encoder (rate 1/2, K = 3, (7,5) generators)
Each input bit is shifted into a K-bit shift register; two output bits are computed as the XOR of the register taps defined by the generator polynomials g1 = 111 and g2 = 101. The tail bits (K-1 zeros) flush the register back to state 0. The state diagram below shows all 2K−1 = 4 states and the transitions; the same structure forms the trellis for the Viterbi decoder on the next tab.
State diagram: each circle is a state (the K−1 most recent input bits). Edge label "in/out1,out2" = input bit → output pair.
⑤ Viterbi decoder (ACS on the trellis)
For each column of the trellis, the Viterbi decoder adds the branch metric (Hamming distance between received pair and expected output) to the path metric of the source state, keeps the smaller, and records the survivor. After all columns, traceback from the best final state recovers the decoded bits. This is the MLSD (maximum-likelihood sequence detection) for convolutional codes over hard-decision channels.
Trellis (x: time, y: state, edge label: "in / out pair / branch metric"). Highlighted path is the survivor. Final path metric in KV panel.
📖 Deep-dive blog (planned)
Shannon's channel-coding theorem — for any rate R < C, there exists a code with BER → 0; for R > C, BER → ½. Capacity-approaching codes (LDPC, Turbo, Polar) approach this limit.
Hamming codes — the first non-trivial ECC (1950). Why 2r−1 codeword length for r parity bits, and the geometric interpretation of dmin = 3.
CRC design — how to pick a polynomial (irreducible, primitive, with good burst-error coverage). The 16 standard CRC polynomials and their use cases.
Convolutional codes — state, trellis, and the connection to linear time-invariant systems over GF(2). Why (7,5) is the canonical K=3 code.
Viterbi algorithm — derived from dynamic programming. ACS (add-compare-select) at each trellis step. Survivor-path memory and traceback depth.
Soft-decision Viterbi — replacing Hamming distance with Euclidean distance. ~2 dB coding gain over hard-decision at the same complexity.
Coding gain at low BER — the (7,5) code at BER = 10−5 gives ≈ 4 dB coding gain. Turbo codes (1993) get within 0.5 dB of capacity; LDPC codes (1962, rediscovered 1995) match that.
Status: scaffold shipped (engine + page). Blog content to follow.
Block code (live)
Code parameters
Code:—
(n, k):—
Rate R = k/n:—
dmin:—
t = ⌊(d−1)/2⌋ (correct):—
d−1 (detect):—
Hamming demo (live)
Encode / decode
Message m:—
Codeword c:—
Received r:—
Syndrome s:—
Decode status:—
Corrected c':—
CRC (live)
Polynomial
Poly:—
Hex:—
Init:—
Computation
Message length:—
CRC (hex):—
CRC (bits):—
Convolutional / Viterbi (live)
Encoder
Generators:—
Constraint K:—
Input length:—
Output length:—
Viterbi
States:—
Final path metric:—
Bit errors:—
BER:—
🚫 Pitfall: Don't trust the Hamming demo for double errors. The (7,4) code can correct 1 error or detect 2; the syndrome for a 2-bit error pattern is the sum (XOR) of two single-bit syndromes, which can match another single-bit syndrome. Result: wrong correction, no warning.
⚠ Soft vs hard decision: This page uses hard-decision Viterbi (input bits, not LLRs). Real systems (5G, satellite) use soft-decision Viterbi or BCJR with LLR inputs — ≈ 2 dB additional coding gain at the same code.