Field Guide · algorithm

Also known as: Hamming(10,6,3), P25 short Hamming, 10-6 Hamming code

The P25 Hamming(10,6,3) code is the single-error-correcting inner Hamming code that P25 (TIA-102.BAAA) applies to each 6-bit fragment of the Link Control and Encryption Sync words carried inside an LDU.1 Each codeword is 6 data bits plus 4 parity bits; a full 240-bit LC/ES field is 24 of them, and the recovered 24 × 6 = 144 bits become the symbols of the outer Reed-Solomon code that cleans up whatever the Hamming layer misses.

d0 d1 d2 d3 d4 d5 p0 p1 p2 p3 syndrome = recomputed parity XOR received parity → 4-bit value naming the one flipped bit (0 = clean)
Six data bits and four parity bits make a distance-3 codeword; the 4-bit syndrome uniquely identifies which of the ten positions flipped, letting the decoder correct any single-bit error.

How it works

The code is defined by six fixed 4-bit parity columns, one per data bit; the parity nibble is the XOR of the columns of the set data bits. The four parity bits themselves occupy the four unit columns 0x8/0x4/0x2/0x1, so all ten columns are distinct and nonzero — the property that makes a distance-3 (single-error-correcting) code. GopherTrunk’s parity columns are:

Data bit d0 d1 d2 d3 d4 d5
Parity column 0x7 0xB 0xD 0xE 0x3 0x5

On decode, the receiver recomputes parity over the six received data bits and XORs it against the four received parity bits to form a 4-bit syndrome. A zero syndrome means the codeword is clean. A nonzero syndrome is matched against the six data columns and the four unit columns: whichever column it equals names the single flipped bit, which is then corrected. Because the code has distance 3, it can correct one error or detect two, but a two-bit error lands on a syndrome that points at the wrong single bit — which is precisely why P25 wraps 24 of these codewords in an outer RS code that operates on whole 6-bit symbols.

In practice

The 6-bit data width is not an accident: each Hamming codeword’s six data bits are exactly one GF(2⁶) symbol of the outer RS(24,12,13) (Link Control) or RS(24,16,9) (Encryption Sync) codeword. So the two layers compose cleanly — the inner Hamming pass fixes scattered single-bit hits and hands 24 six-bit symbols up, and the outer RS pass corrects up to t whole symbols the Hamming layer got wrong or silently miscorrected. This concatenation is what keeps a talkgroup or crypto Message Indicator intact through the marginal SNR where a bare Hamming layer would let bit errors slip through into the payload.

Relevance to SDR

internal/radio/p25/phase1/hamming10_6.go implements this locally rather than reusing the framing package’s (15,11) and (13,9) shortenings, because P25’s LC/ES fragments are exactly 6 bits wide. lcInnerDecode runs the 24 codewords across a 240-bit LC/ES field and returns the 144 data bits plus a corrected-error count, which the Link Control and Encryption Sync parsers feed straight into the outer RS layer. It is a small, table-driven code, but getting its parity columns right is a precondition for reading any voice-channel metadata on P25 Phase 1.

Sources

  1. Hamming code — Wikipedia, on the single-error-correcting block codes this shortening belongs to. 

See also