Correzione degli errori: VRC/LRC e codici di Hamming

// obiettivi di apprendimento
Distinguere rilevazione e correzione degli errori, capire quando usare ciascuna tecnica
Calcolare il bit di parità VRC e costruire un blocco LRC su una sequenza di byte
Comprendere la struttura del codice di Hamming e posizionare i bit di parità
Applicare il processo di codifica e decodifica Hamming(7,4) su un esempio reale
📄
Slides
Schema VRC/LRC e tabella costruzione Hamming(7,4)
🔗
Risorse
Esercizi svolti e soluzioni
Vedi →

Rilevare vs Correggere

Nella lezione precedente abbiamo visto come CRC e checksum rilevano gli errori: il ricevitore sa che qualcosa è andato storto, ma non sa dove né come rimediare. La reazione possibile è una sola — chiedere la ritrasmissione.

Esiste però una categoria di codici più potenti, i codici a correzione di errori (ECC — Error Correcting Codes), che aggiungono abbastanza ridondanza da permettere al ricevitore di identificare il bit sbagliato e correggerlo senza ritrasmissione. Il prezzo è un overhead di bit più elevato.

// definizione formale
Un codice (n, k) trasmette k bit di dato in una codeword di n bit totali, aggiungendo r = n − k bit di ridondanza. Il rate di codifica è R = k/n. Più R è basso, più la ridondanza è alta.

Tre parametri guidano la scelta del codice: la probabilità di errore del canale, il costo della ritrasmissione (latenza, banda), e la complessità hardware/software accettabile.

VRC — Vertical Redundancy Check

Il VRC è il più semplice dei codici di correzione/rilevazione: aggiunge un solo bit di parità a ogni carattere (di solito 7 bit ASCII). Il bit di parità viene scelto in modo che il numero totale di 1 nel byte sia pari (parità pari) o dispari (parità dispari). Il protocollo deve concordare quale schema usare.

Esempio pratico — parità pari

CarattereBit dato (7)N. di 1Bit paritàByte trasmesso (8 bit)
‘A’ (65)100 00012 → già pari01000 0010
‘B’ (66)100 00102 → già pari01000 0100
‘C’ (67)100 00113 → dispari11000 0111
‘K’ (75)100 10114 → già pari01001 0110

Il ricevitore ricalcola la parità sull’intero byte: se il numero di 1 è dispari (schema pari) c’è errore.

// attenzione — limite

VRC rileva solo un numero dispari di errori nel byte. Se si invertono 2 bit, la parità rimane invariata e l’errore passa inosservato. Non corregge: il ricevitore sa che c’è un errore, ma non può identificare quale bit è sbagliato.

LRC — Longitudinal Redundancy Check

LRC estende il concetto di parità all’intero blocco di dati: invece di calcolare la parità colonna per colonna (VRC), la calcola riga per riga, producendo un byte di controllo aggiuntivo (BCC — Block Check Character) alla fine del blocco.

Visivamente, immagina il blocco come una matrice di byte: VRC controlla ogni colonna (bit per bit nel singolo byte), LRC controlla ogni riga (lo stesso bit-position in tutti i byte del blocco).

Esempio — blocco di 4 byte

Byteb7b6b5b4b3b2b1b0VRC
‘T’ 84010101001
‘E’ 69010001011
‘S’ 83010100110
‘T’ 84010101001
BCC (LRC)00010110

Ogni colonna del BCC è la parità XOR dei bit di quella posizione in tutti i byte del blocco. Combinando VRC e LRC insieme, il ricevitore può spesso localizzare il bit errato come intersezione di riga e colonna.

// nota

VRC + LRC insieme offrono una capacità di correzione di singolo errore: la riga (LRC) identifica il byte errato, la colonna (VRC) identifica il bit errato. Tuttavia questa tecnica è stata in gran parte sostituita da CRC per la rilevazione e da Hamming per la correzione.

Il Codice di Hamming

Nel 1950 Richard Hamming, lavorando ai Bell Labs, sviluppò un sistema elegante per inserire bit di parità in posizioni strategiche all’interno della codeword, in modo che ogni bit di parità copra un sottoinsieme diverso dei bit di dato. Questo permette, in caso di errore singolo, di identificare esattamente la posizione del bit errato e correggerla.

// principio di Hamming
Per proteggere k bit di dato sono necessari r bit di parità tali che 2ʳ ≥ r + k + 1. I bit di parità occupano le posizioni che sono potenze di 2: 1, 2, 4, 8, 16… Le posizioni rimanenti ospitano i bit di dato.

Hamming(7,4): 4 bit di dato → 7 bit totali

Caso più noto: k=4 bit dati, r=3 bit paritàn=7 bit totali. Verifica: 2³ = 8 ≥ 3+4+1 = 8

Posizione1234567
TipoP1P2d1P3d2d3d4
Copre posiz.1,3,5,72,3,6,74,5,6,7
// copertura dei bit di parità (regola binaria)
P1 (pos 1 = 001) → copre tutte le posizioni con il bit 0 = 1 → pos 1,3,5,7
P2 (pos 2 = 010) → copre tutte le posizioni con il bit 1 = 1 → pos 2,3,6,7
P4 (pos 4 = 100) → copre tutte le posizioni con il bit 2 = 1 → pos 4,5,6,7
La copertura è definita dalla rappresentazione binaria della posizione: se il bit i-esimo è 1, il bit di parità Pᵢ copre quella posizione.

Codifica: esempio con dato 1011

Dato da trasmettere: d1=1, d2=0, d3=1, d4=1 → inseriti nelle posizioni 3, 5, 6, 7.

Pos1 (P1)2 (P2)3 (d1)4 (P4)5 (d2)6 (d3)7 (d4)
Valore dato??1?011
Calcolo parità (pari)P1: pos 1,3,5,7 → ?,1,0,1 → tre 1 → P1=1  |  P2: pos 2,3,6,7 → ?,1,1,1 → tre 1 → P2=1  |  P4: pos 4,5,6,7 → ?,0,1,1 → due 1 → P4=0
Codeword finale1110011

La codeword trasmessa è: 1110011

Decodifica e correzione dell’errore

Supponiamo che durante la trasmissione si alteri il bit in posizione 5 (cambia da 0 a 1). Il ricevitore ottiene: 1110111.

Il ricevitore ricalcola le sindromi (parità dei gruppi): se il risultato è 0 tutto ok, se è 1 c’è un errore nel gruppo.

// calcolo sindromi sul messaggio ricevuto 1110111
S1 (pos 1,3,5,7): 1 ⊕ 1 ⊕ 1 ⊕ 1 = 0errore rilevato → S1=1
S2 (pos 2,3,6,7): 1 ⊕ 1 ⊕ 1 ⊕ 1 = 0 → ok → S2=0
S4 (pos 4,5,6,7): 0 ⊕ 1 ⊕ 1 ⊕ 1 = 1errore rilevato → S4=1
Sindrome = S4S2S1 = 101 (binario) = 5 in decimale → bit errato in posizione 5

Il ricevitore inverte il bit in posizione 5 e ottiene la codeword corretta: 1110011. Estrae i bit di dato dalle posizioni 3,5,6,7: 1,0,1,1 → dato originale recuperato correttamente.

// insight chiave

La sindrome è esattamente la posizione binaria del bit errato. Se sindrome = 000 non ci sono errori. Se sindrome ≠ 000, il suo valore decimale indica il bit da invertire. Questo è il meccanismo elegante di Hamming: le posizioni delle parità non sono casuali, sono le potenze di 2 proprio per sfruttare la rappresentazione binaria come “indirizzo” dell’errore.

Distanza di Hamming

La distanza di Hamming tra due codeword è il numero di bit in cui differiscono. Per un codice con distanza minima d:

Distanza minima dCapacità di rilevazioneCapacità di correzione
d = 2Rileva 1 erroreNon corregge
d = 3Rileva 2 erroriCorregge 1 errore (Hamming base)
d = 4Rileva 3 erroriCorregge 1 + rileva 2 (Hamming esteso con bit globale)
d = 2t+1Rileva 2t erroriCorregge t errori

Hamming(7,4) ha distanza minima d=3: corregge 1 errore e rileva 2. La variante Hamming(8,4) esteso aggiunge un bit di parità globale (SECDED — Single Error Correction, Double Error Detection), con d=4.

ECC nella pratica moderna

I codici di Hamming si trovano ancora oggi in memoria RAM ECC dei server, dove un singolo bit-flip può causare corruzione silenziosa dei dati. I moduli RAM ECC aggiungono chip extra (tipicamente 8 o 9 chip invece di 8) per memorizzare i bit di parità Hamming. La correzione avviene in hardware, in modo trasparente al processore.

// dove lo vedi nel mondo reale

RAM ECC nei server — corregge bit-flip causati da raggi cosmici. NAND Flash nei SSD — usa BCH o LDPC (evoluzioni di Hamming). Voyager e sonde spaziali — Reed-Solomon + codici convoluzionali per canali con alta perdita di segnale. CD/DVD — CIRC (Cross-Interleaved Reed-Solomon) per correggere i graffi. Hamming è il capostipite di tutti questi sistemi.

📌 Riepilogo — Punti chiave
  • VRC: parità su singolo byte. Rileva errori in numero dispari nel byte. Semplice, overhead 1 bit/byte.
  • LRC: parità longitudinale sul blocco (BCC). Combinato con VRC permette di localizzare il bit errato.
  • Hamming(n,k): i bit di parità occupano le posizioni potenze di 2. Ogni bit di parità copre le posizioni il cui indice ha quel bit a 1 in binario.
  • La sindrome è l’indirizzo binario del bit errato: se non è zero, il suo valore decimale indica esattamente quale bit invertire.
  • Hamming(7,4): distanza minima 3 → corregge 1 errore, rileva 2. Efficienza k/n = 4/7 ≈ 57%.
  • Applicazioni reali: RAM ECC, NAND Flash, sonde spaziali, storage. È il fondamento concettuale di tutti i codici ECC moderni.

Lascia un commento