Der Hamming-Code (7,4) stammt aus dem Jahr 1950. Damals arbeitete Richard Hamming als Mathematiker bei Bell Labs. Jeden Freitag stellte Hamming die Rechenmaschinen auf eine Reihe von Berechnungen ein und sammelte die Ergebnisse am folgenden Montag. Mithilfe von Paritätsprüfungen konnten diese Computer Fehler während der Berechnung erkennen. Frustriert, weil er viel zu oft Fehlermeldungen erhielt, beschloss Hamming, die Fehlererkennung zu verbessern, und entdeckte die berühmten Hamming-Codes.
Mechanik der Hamming (7,4)
Das Ziel von Hamming-Codes besteht darin, einen Satz von Paritätsbits zu erzeugen, die sich so überlappen, dass ein Einzelbitfehler (ein Bit wird umgedreht) in einem Datenbit oder einem Paritätsbit erkannt und korrigiert werden kann. Nur wenn mehrere Fehler auftreten, kann der Hamming-Code die ursprünglichen Daten nicht wiederherstellen. Möglicherweise wird ein Fehler überhaupt nicht bemerkt oder sogar falsch korrigiert. Daher werden wir uns in dieser Herausforderung nur mit Einzelbitfehlern befassen.
Als Beispiel für die Hamming-Codes betrachten wir den Hamming-Code (7,4). Zusätzlich zu 4 Datenbits d1, d2, d3, d4
werden 3 Paritätsbits verwendet p1, p2, p3
, die mit den folgenden Gleichungen berechnet werden:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
Das resultierende Codewort (Daten + Paritätsbits) hat die Form p1 p2 d1 p3 d2 d3 d4
.
Das Erkennen eines Fehlers funktioniert folgendermaßen. Sie berechnen die Paritätsbits neu und prüfen, ob sie mit den empfangenen Paritätsbits übereinstimmen. In der folgenden Tabelle können Sie sehen, dass jede Sorte eines Einzelbitfehlers eine andere Übereinstimmung der Paritätsbits ergibt. Daher kann jeder Einzelbitfehler lokalisiert und korrigiert werden.
error in bit | p1 | p2 | d1 | p3 | d2 | d3 | d4 | no error
-------------|---------------------------------------------
p1 matches | no | yes| no | yes| no | yes| no | yes
p2 matches | yes| no | no | yes| yes| no | no | yes
p3 matches | yes| yes| yes| no | no | no | no | yes
Beispiel
Lassen Sie Ihre Daten sein 1011
. Die Paritätsbits sind p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
und p3 = 0 + 1 + 1 = 0
. Kombinieren Sie die Daten und die Paritätsbits und Sie erhalten das Codewort 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Sagen wir, während einer Übertragung oder einer Berechnung wird das 6. Bit (= 3. Datenbit) umgeschaltet. Du erhältst das Wort 0110001
. Die angeblich erhaltenen Daten sind 1001
. Sie berechnen die Parity - Bits wieder p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. p1
Stimmt nur mit den Paritätsbits des Codeworts überein 0110001
. Daher ist ein Fehler aufgetreten. In der obigen Tabelle sehen Sie, dass der Fehler in aufgetreten ist d3
und Sie die ursprünglichen Daten wiederherstellen können 1011
.
Herausforderung:
Schreiben Sie eine Funktion oder ein Programm, das ein Wort (7 Bits) empfängt, eines der Bits ist möglicherweise falsch, und stellen Sie die ursprünglichen Daten wieder her. Das Eingabeformat (über STDIN, Befehlszeilenargument, Eingabeaufforderung oder Funktionsargument) kann eine Zeichenfolge "0110001"
, eine Liste oder ein Array [0, 1, 1, 0, 0, 0, 1]
oder eine Ganzzahl in MSB sein 0b0110001 = 49
. Wie oben beschrieben ist die Reihenfolge der Eingabe p1 p2 d1 p3 d2 d3 d4
. Die Ausgabe (über Rückgabewert oder STDOUT) muss dasselbe Format haben, jedoch in der Reihenfolge d1 d2 d3 d4
. Nur die 4 Datenbits zurückgeben / ausgeben.
Das ist Code-Golf. Daher gewinnt der kürzeste Code.
Testfälle:
1110000 -> 1000 # no error
1100000 -> 1000 # error at 1st data bit
1111011 -> 1111 # error at 2nd data bit
0110001 -> 1011 # error at 3rd data bit (example)
1011011 -> 1010 # error at 4th data bit
0101001 -> 0001 # error at 1st parity bit
1010000 -> 1000 # error at 2nd parity bit
0100010 -> 0010 # error at 3rd parity bit
[is_p3_wrong][is_p2_wrong][is_p1_wrong]
Basis zwei verwenden, wird die Position des falschen Bits im Wort angegeben. (Basierend auf der Tabelle in der Frage.) Dies wird wahrscheinlich für einige Algorithmen nützlich sein.