Proseminar: Redundanz

Vortrag 2: Grundlagen der Fehlererkennung und -korrektur

Dirk Focken



Warum und wann braucht man Fehlererkennnung/korrektur?

Viele kennen aus zeitraubenden Erfahrungen, dass lange Datenübertragung per Modem dann und wann mit Fehlern behaftet sind. Hat man in diesen Fällen im jeweiligen Übertragungsprotokoll keine Fehlererkennung, so merkt man erst nach der langen Übertragung, dass man noch mal von vorne beginnen kann. Gesellt sich neben Fehlererkennung gar Fehlerkorrektur zu den Merkmalen des Protokolls, darf man sich, wenn Fehler auftreten, gewiß freuen, ein solches Protokoll gewählt zu haben.

Man erkauft sich diese Fehlersicherheit zum Preis einer etwas längeren Datenübertagung als es bei einer immer fehlerfreien Leitung nötig ist, da neben den eigentlichen Daten auch Prüfdaten übertragen werden müssen. Man nennt diese Prüfdaten treffender Redundanz und so eine Datenübertragung redundante Datenübertragung.

Es ist immer abzuwägen, in welchem Ausmaß eine Datenübertragung über einen bestimmten Kanal (sei's ein Modem, SCSI-Bus, etc.) Fehlererkennung bzw. Fehlerkorrektur bedarf oder ob zuviel Sicherheit (längere Übertragung wegen zusätzlichen Prüfdaten) zu einem unvertretbaren Leistungseinbuße führt.

Beispiel: Datenfernübertragung (DFÜ)

Für Übertragung von Daten über eine Modemleitung ist es sicher angebracht, irgendeine Fehlererkennung im Protokoll zu haben. Hier ist aber meist von fehlerkorrigierenden Protokollen abzuraten, da diese nur Fehler korrigieren können, wenn sie vereinzelt auftreten. Bei einer Modemverbindung treten Fehler jedoch meist in einem Büschel (burst) auf.
So ist es besser die Datenübertragung in kleine unabhängige Pakete aufzuteilen und Fehlererkennung zu benutzen. Treten nun Fehler gehäuft auf, wird dies erkannt und man sendet nochmal das Datenpaket, in dem Fehler auftraten.
Hingegen ist es sicher nicht ratsam, den internen Bus eines Prozessors mit redundanten Informationen zur Fehlererkennung zu belasten, wenn dieser Bus ohnehin keine Fehler produziert.

Beispiel: Datenübertragung auf Zeit: Datenspeicherung

Man kann das Speichern von Daten auch als eine Datenübertragung über einen längeren Zeitraum ansehen. Das Senden von Daten entspricht das Schreiben auf ein Speichermedium, und das Empfangen entspricht dem Lesen. Dazwischen vergeht Zeit, in der das Speichermedium zerkratzt oder auf andere Art verändert wird, beim Lesen der Daten kann es so zu Fehlern kommen.
Daher kann auch Fehlererkennung bzw. Fehlerkorrektur für das Speichern von Nutzen sein. Wie im Beispiel der DFÜ ist hier wieder abzuwägen, in wie weit Fehlererkennung nötig ist.

Man braucht für das Abspeichern einer längeren einfachen Textdatei meist keine Sicherheitsvorkehrungen zu treffen. Selbst wenn ein paar Bytes hintereinander falsch sind, so ist nur ein Wort im Text unleserlich, was nicht soviel ausmacht, da der Mensch meist aus dem Satzzusammenhang den Fehler korrigieren kann. Also ist eine Textdatei ohnehin ausreichend redundant.
Ganz anders sieht es bei einer gepackten ZIP-Datei aus. Hat nur ein einziges Zeichen einen Fehler so kann die Datei vollständig unbrauchbar sein, da die Informationen darin nicht redundant, sondern gerade dicht gepackt sind. Daher nutzt das ZIP Format immer eine CRC Prüfung (Cyclic Redundancy Code) , um wenigstens Fehler erkennen zu können.
Ein weiteres Beispiel sind ausführbare Dateien (z.B. EXE-Dateien, Binaries,etc.). Wird hier nur ein Bit verändert, so kann das Programm bei nächster Ausführung deswegen Abstürzen.

Grundlagen der Fehlererkennung/korrektur

Was ist eigentlich Fehlererkennung/korrektur?

Um sich einen Überblick zu verschaffen, wie Fehlererkennung/korrektur genau funktioniert, geht man von dem abstrakten Schema der Nachrichten- bzw. Datenübertragung aus.

Bei einer Nachrichtenübertragung mit Fehlererkennung oder Fehlerkorrektur muß man in der Dekodierphase die Fehler, die durch das Rauschen des Übertragungskanals entstanden sind, entdecken bzw. korrigieren können. Ein Fehler bedeutet dabei (und soll im folgenden immer so verstanden werden), daß der Sender ein Kodezeichen in den Kanal gibt, aber durch das Kanalrauschen ein anderes Kodezeichen beim Empfänger ankommt.

Notwendigkeit von Redundanz für Fehlererkennung und erläuterndes Beispiel

In der Einführung wurde schon angesprochen, dass Fehlererkennung nur durch Redundanz zu erreichen ist. Um das noch klarer zu machen, betrachte man folgendes:

Es sei eine Quelle mit vier verschiedenen Symbolen gegeben (z.B. rechts, links, oben und unten) und man kodiert diese Symbole binär

Überträgt man über einen Kanal diese zwei Bit langen Kodewörter und wird durch einen Fehler eine 0 zu einer 1 oder umgekehrt, so ist aus dem ursprünglichen Kodewort ein anderes gültiges Kodewort entstanden.
Im Dekodierschritt ist dies unmöglich zu erkennen, d.h. wenn ein Fehler beim Übertragen des Kodewortes auftritt, darf kein gültiges Kodewort dadurch erzeugt werden. Ein auftretender Fehler muß ein ungültiges Kodewort erzeugen, damit der Fehler erkannt werden kann.
Also kann man nicht alle möglichen Kodewörter benutzen, um sie mit Quellsymbolen zu identifizieren (hier rechts,links,etc.). Es müssen einige Kodewörter verbleiben, die keinem Quellsymbol zugeordnet werden.
Man verschwendet diese Kodewörter, um Fehler erkennen zu können.
Diese für die eigentliche Datenübertragung "überflüssigen" Kodewörter stellen die Redundanz des Kodes oder der Übertragung dar.

Im obigen Beispiel könnte man die Kodewörter um ein Paritätsbit verlängern, d.h. man zählt in jedem Kodewort die Einsen und ist die Anzahl gerade, so schreibt man hinter das Kodewort eine Null sonst eine Eins.
Gültige Kodewörter sind somit

die ungültigen Kodewörter sind 001 010 100 111.
Es gibt im ganzen 2^3 = 8 mögliche Kodewörter, also sind 4 Kodewörter gültig und 4 ungültig. Wandelt sich durch einen Übertragungsfehler eine beliebige Stelle in einem gültigen Kodewort von einer 1 zur 0 oder umgekehrt, so wird das empfangene Kodewort ungültig sein. Also kann dieser einzelne Fehler in der Dekodierphase erkannt werden. Ein Paritycheck erzeugt einen einzelfehlererkennenden Kode.

Fehlererkennung mit Paritätsprüfung erkennt einen Fehler

Es existiert keine perfekte Fehlererkennung/korrektur

Man muß sich dabei vor Augen halten, dass beim Auftreten einer geraden Anzahl von Übertragungsfehlern wieder ein gültiges völlig anderes Kodewort erzeugt wird und somit die Fehlererkennung versagt: Man hat mehr Sicherheit erreicht, aber es gibt immer ein Restrisiko.

Fehlererkennung mit Paritätsprüfung versagt bei zwei Fehlern

Fehlerkorrektur

Wenn man einen Fehler erkannt hat, so sollte man ihn doch auch korrigieren können. Nach obiger Diskussion erkennt man einen Fehler, wenn man ein ungültiges Kodewort empfängt. Die beste Korrektur wäre das ähnlichste gültige Kodewort durch das ungültige zu ersetzen.
Aber was genau ist das Ähnlichste?

Das hängt davon ab, welche Art von Rauschen der Übertragungskanal hat: In der Theorie wird gerne ein Kanal mit weißem Rauschen genommen, d.h. Kodezeichen werden alle mit der gleichen Wahrscheinlichkeit unabhängig voneinander verfälscht.
Menschen als Übertragungskanal rufen ein völlig anderes Rauschen hervor, sie verdrehen zum Beispiel Kodezeichen, was eine elektrische Leitung nur schwerlich leisten könnte.

Fortan werden nur die Kanäle betrachtet, die überwiegend weißes Rauschen besitzen (Hier geht es um die Theorie).
Unter diesen Bedingungen treten Fehler unabhängig voneinander mit der gleichen Wahrscheinlichkeit auf. Bekommt der Empfänger ein ungültiges Kodewort, wurde mit der größten Wahrscheinlichkeit das gültige Kodewort gesendet, das sich von dem ungültigen Kodewort in den wenigsten Stellen unterscheidet.

Im vorigen Beispiel gibt es aber ein Problem, man hat mehrere gültige Kodewörter, die sich in der genau gleichen minimalen Anzahl von Kodestellen unterscheiden:

        Ungültig   Gültig und Unterschied 1 Bit
        
        001        000 rechts 011 unten
        010        011 unten  110 oben
        100        101 links  000 rechts
        111        101 links  110 oben 

Man kann so ziemlich schlecht den Fehler korrigieren, weil man sich für eines von zwei gleich wahrscheinlich echten Kodeworten entscheiden muß. Also scheint mit dem einfachen Paritybit eine Fehlerkorrektur eines einzelnen Fehlers nicht möglich zu sein.

In obigem Beispiel hatten wir einen Kode der Länge 3 mit 2 Datenbits und 1 Prüfbit. Nimmt man aber anstatt einem k Prüfbits, kann man theoretisch 2^k verschiedene Zustände darstellen anstatt mit einem Prüfbit nur 2^1 = 2 Zustände. Wenn man ein binäres Kodewort der Länge n hat, müsste man bei Fehlerkorrektur sagen können, an welcher der n Stellen der Fehler auftrat oder ob kein Fehler aufgetreten ist: Das sind n+1 verschiedene Zustände und daher muß folgendes gelten

            2^k >= n+1.
Die k Prüfbits müssen mindestens die n verschiedenen Stellen darstellen können, an denen ein Fehler auftrat und ebenso, dass kein Fehler auftrat.

Hammingkode

Wie konstruiert man den Kode, der diese Ungleichung auch genau erfüllt also zur Gleichung macht?
Die Idee hinter diesem als Hammingkode bekannten Kode ist, dass die k Prüfbits die Stelle an der, der Fehler auftrat, als k-Bit Binärzahl darstellen. Wenn kein Fehler auftrat, sollen die Prüfbits eine 0 darstellen.

Ein Kodewort besteht aus k Kontrollstellen und den eigentlichen m Datenbits, was zusammen ein Kodewort der Länge m+k=n macht.
Ein Prüfbit soll dabei eine Art Paritätsprüfung ermöglichen, d.h. wenn das endgültige Kodewort beim Empfänger ankommt, so soll der Empfänger folgendes für jedes Prüfbit tun:
Je nach Prüfbit addiert er einige bestimmte Datenbits und zählt noch das Prüfbit dazu, dann teilt er das Ergebnis ganzahlig durch 2 und betrachtet den Rest der Division. Kommt 0 heraus so ist in den betrachteten Datenbits und im Prüfbit kein einzelner Fehler aufgetreten. Ist der Rest dagegen 1, so muß in einem dieser Bits ein Fehler aufgetreten sein. Da für jedes der k Prüfbits eine solche Prüfprozedur durchgeführt wird, hat man k verschiedene Ergebnisse vom Wert 0 oder 1. Man kann diese Ergebnisse hintereinander schreiben und erhält eine Binärzahl, die auch Syndrom genannt wird. Diese Binärzahl soll gemäß der Idee des Hammingkodes die Fehlerstelle darstellen. Für diese Zahl oder auch Syndrom muß folgendes gelten

        Fehler passiert an Position        Syndrom muß dies darstellen

        1                                   0001    
        2                                   0010
        3                                   0011
        4                                   0100
        5                                   0101
        6                                   0110
        7                                   0111
        8                                   1000
        9                                   1001
        10                                  1010
        .                                     .
        .                                     .
        .                                     .
Daraus kann man ablesen, dass das letzte Prüfbit die Positionen 1,3,5,7,.. in seiner Paritätsprüfung enthalten muß, das vorletzte Prüfbit 2,3,6,7,10,11,... das zweitletzte die Stellen 4,5,6,7,12,13,14,15,... und sofort.

Man kann diesen Kode für den Fall konstruieren, vier Datenbits mit Einzelfehlerkorrektur zu versehen. Nach obiger Ungleichung muß gelten

 2^k >= n+1 = m+k+1 = 4+k+1 
Für k = 3 ist die Ungleichung genau erfüllt
 8=2^3 >= 4+3+1 = 8 
Das Kodewort hat also die Länge 7 und man hat 4 Datenbits und 3 Prüfbits. Um es möglichst einfach zu haben, werden hier die Stellen des Kodeworts von rechts nach links durchnummeriert und als Prüfbits werden die 1.,2. und 4. Stelle des Kodeworts gewählt, d.h. die eigentlichen Datenbits befinden sich an der 3.,5.,6. und 7. Stelle des Kodeworts.
   Stellen     7 6 5 4 3 2 1 
   Bits        _ _ _ _ _ _ _
   Daten       * * *   *
   Prüfbits          K   K K 
Angenommen man will 1011 kodieren, so schreibt man die eigentlichen Daten zuerst in die Datenbits, um danach die einzelnen Paritätsbits zu berechnen.
   Stellen     7 6 5 4 3 2 1 
   Bits        1 0 1 _ 1 _ _

   Prüfung #1  1+0+1+0        = 0 (in mod 2 gerechnet) 

               1 0 1 0 1 _ _

   Prüfung #2  1+0+    1+0    = 0 (in mod 2 gerechnet)

               1 0 1 0 1 0 _

   Prüfung #3  1+  1+  1+  1  = 0 (in mod 2 gerechnet)

               1 0 1 0 1 0 1

Endgültiges Kodewort 1 0 1 0 1 0 1

Ergebnis von Prüfung #1,#2,#3: 0 0 0 
Zuerst sucht man den Wert des ersten Prüfbits, das sich an Stelle 4 befindet. Das erste Prüfbit ist das zweitletzte. Nach obiger Idee muß die Paritätsprüfung somit über die Stellen 4,5,6,7 ausgeführt werden. Man addiert diese Stellen 1+0+1+x = 2+x; dabei ist das x das erste Prüfbit an Stelle 4. Welchen Wert soll man dafür wählen? 2+x muß durch zwei geteilt den Rest 0 ergeben, das heißt nichts anderes als 2+x muß durch zwei teilbar sein, also wählt man für x eine 0. Man muß an Stelle 4 eine 0 schreiben.
Das Kodewort ist jetzt 1 0 1 0 1 _ _.

Nun wird der Wert des zweiten bzw. vorletzten Prüfbits gesucht, das sich an Stelle 2 befindet. In der Paritätsprüfung des vorletzten Prüfbits müssen die Stellen 2,3,6,7 betrachtet werden. Man hat 1+0+1+x = 2+x. Also muß man eine 0 an Stelle 2 schreiben.
Schließlich muß das letzte Prüfbit an Stelle 1 die Prüfung über die Stellen 1,3,5,7 vollziehen; dies ergibt 1+1+1+x = 3+x. x muß 1 sein damit 3+x durch 2 teilbar ist (Rest der Division 0). Daher muß eine 1 an Stelle 1 stehen.
Das endgültige Kodewort ist 1 0 1 0 1 0 1 .

Schreibt man die Ergebnisse der Prüfungen #1,#2 und #3 hintereinander so erhält man 000 (Syndrom). Wird das Kodewort ohne Fehler übertragen, führt der Empfänger die drei Paritätsprüfungen durch, schreibt die Ergebnisse hintereinander und erhält dieses Syndrom 000, was "kein Fehler" bedeutet.

Man nehme an, in Stelle 4 des Kodeworts tritt ein Fehler auf. Dann erhält der Empfänger statt

                      1 0 1 0 1 0 1 
                            *
   das Kodewort       1 0 1 1 1 0 1.
Berechnet man das Syndrom, so ergeben die Paritätsprüfungs 100. Es ist ein Fehler an Stelle 4 aufgetreten.
Das Interessante dabei ist, dass dies ein Prüfbit war und kein Datenbit, d.h. es ist gleichgültig ob Daten- oder Prüfbit, wenn ein einzelner Fehler auftritt, wird er erkannt.
Die beachtliche Redundanz von 3 Prüfbits zu 4 Datenbits scheint etwas hoch zu sein. Verlängert man aber das Kodewort auf z.B. 1023 Stellen, so werden die Stellen 1,2,4,8,16,32,64,128,256 und 512 als Prüfbits genutzt. Also 10 Prüfbits und 1012 Datenbits, was vom Redundanzgesichtspunkt her schon wesentlich akzeptabler ist. Auch für diese Kodewortlänge ist die Ungleichung von oben genau erfüllt
 2^k >= n+1, also 2^10 = 1024 >= 1023+1 = 1024.


Hammingdistanz, Hammingkugeln und Hamminggrenze

Der im obigen Abschnitt konstruierte Hammingkode korrigiert genau einen Fehler und ist für bestimmte Kodewortlängen optimal (2^j-1), da er die Ungleichung, die jeder Einzelfehler korrigierende Kode erfüllen muß, nicht nur erfüllt, sondern auch zur Gleichung macht (wie in den Beispielen für die Kodelängen 7 und 1023 gesehen).

Wie sieht es mit Kodes aus, die zwei oder n Fehler korrigieren können, oder kann ein Kode vielleicht n Fehler korrigieren und dabei auch 2*n Fehler erkennen? Welche Ungleichungen müssen solche Kodes erfüllen?
Um diese Fragen zu beantworten, kann man versuchen, das Problem der Fehlerkorrektur von einem anderen Blickwinkel zu betrachten.

Eine geometrische Sicht auf binäre Kodes

Man kann sich ein binäres Kodewort der Länge n als einen Punkt im n-dimensionalen Raum vorstellen, wobei die i. Stelle des Kodeworts die i. Koordinate im n-dimensionalen Raum angibt.
An einer Stelle des Kodeworts steht entweder eine 1 oder 0, so dass es nur zwei Werte für jede Koordinate gibt (0 und 1). Mit n Koordinaten kann man so nur 2^n verschiedene Punkte im n-dimensionalen Raum darstellen, was mit der Zahl der möglichen Kodeworte von 2^n übereinstimmt. Diese 2^n Punkte (Kodewörter) sind die Eckpunkte eines n-dimensionalen Würfels.

Geometrische Sicht auf Binîrkode mit Paritît aus obigem Beispiel

Hammingabstand

Sendet man ein Kodewort, so ist dies ein bestimmter Eckpunkt auf dem Würfel. Tritt im Kanal ein einzelner Fehler auf, so bewegt sich der Kodewortpunkt auf einer bestimmten Kante des Würfels zu einem direkt daneben liegenden Eckpunkt.
Nimmt man an, dass man wieder einen Kode mit Redundanz betrachtet, so gibt es Punkte auf dem Würfel, die gültige Kodewörter darstellen und solche die ungültige darstellen. Fordert man jetzt von diesem Kode, dass der Abstand zwischen zwei gültigen Kodewortpunkten mindestens 2 Kanten beträgt, so ist ein einzelner Fehler immer erkennbar:
Denn sendet man ein gültiges Kodewort und tritt ein einzelner Fehler auf, so wird der Kodewortpunkt um nur eine Kante verschoben , so dass dadurch nie ein gültiger Kodewortpunkt erreicht werden kann, da ja mindestens eine Verschiebung um 2 Kanten dafür nötig ist, um wieder auf einem gültigen Kodewortpunkt zu landen.
Also wird man beim Auftreten eines einzelnen Fehlers immer ein ungültiges Kodewort empfangen und somit ist Einzelfehlererkennung in solch einem Kode gegeben.

Fordert man von einem Kode mit Redundanz darüber hinaus, dass der Minimalabstand zwischen zwei gültigen Kodewörtern 3 Kanten auf dem Würfel beträgt, so läßt ein einzelner Fehler den empfangenen Kodewortpunkt näher an dem ursprünglichen Kodewortpunkt und damit hat man Einzelfehler Korrektur ermöglicht.

Was man durch diese Betrachtungsweise gewonnen hat, ist eine Abstandsfunktion, die Hammingabstand genannt wird. Dieser Hammingabstand gibt an wieviele Kanten man auf dem Würfel mindestens ablaufen muß, um von einem bestimmten Kodewortpunkt A zu einem anderen Kodewort B zu gelangen. Diese Zahl stimmt mit der Anzahl der Binärstellen überein, in denen sich das Kodewort A und B unterscheiden.

Bedeutung des minimalen Hammingabstands eines Kodes

Interessant ist es nun in einem binären Kode den kleinsten Hammingabstand, den zwei gültige Kodewörter haben können, zu betrachten. Dieser Abstand wird auch minimaler Hammingabstand des Kodes genannt.
Ein Kode mit minimalem Hammingabstand von 1 ermöglicht keine Fehlererkennung (abändern einer Stelle führt wieder auf ein gültiges Kodewort), ein Kode mit minimalem Hammingabstand von 2 gewährt Einzelfehlererkennung, von 3 ermöglicht entweder Doppelfehlererkennung oder Einzelfehlerkorrektur, da bei einem Fehler der empfangene Kodewortpunkt näher beim ursprünglichen Kodewortpunkt liegt als zu irgendeinem anderen gültigen Kodewort.
Mit einem Kode mit minimaler Hammingdistanz von 5 ist eine Doppelfehlererkennung möglich.

Minimaler Hammingabstand   Möglichkeiten
des Kodes                
        1                  keine Fehlererkennung
        2                  Einzelfehlererkennung
        3                  Einzelfehlerkorrektur oder Doppelfehlererkennung
        4                  Einzelfehlerkorrektur und Doppelfehlererkennung
                           oder Dreifachfehlererkennung 
        5                  Doppelfehlerkorrektur oder Vierfachfehlererkennung
        etc.

Hammingkugeln

Es verbleibt noch die Ungleichungen, die solche Kodes erfüllen müssen aufzustellen, dazu braucht man noch den der Begriff der Hammingkugel, welcher eine Umgebung, um einen bestimmten Kodewortpunkt A darstellt:
Eine Hammingkugel mit dem Radius r um einen Kodewortpunkt A ist die Menge von Kodewortpunkten, deren Hammingabstand zum Punkt A kleiner gleich dem Radius r ist.

Zum Beispiel hat man bei einem binären Kode mit 3 Stellen einen 3-dimensionalen Würfel mit 2^3 = 8 Eckpunkten, d.h. 8 mögliche Kodeworte.
Eine Hammingkugel mit Radius 1, um das Kodewort 110 bzw. um den Kodewortpunkt (0,1,0) enthält 4 Kodewörter oder auch 4 Kodewortpunkte, nämlich das Kodewort 110 selbst und 3 Kodewortpunkte, die man über eine der 3 Kanten erreichen kann, die im Punkt 010 enden. Diese Kodewortpunkte sind 010, 100, 111. Hier sieht man nochmals im Beispiel, dass das Abwandern einer Kante nichts anderes darstellt als das Abändern einer Stelle im Kodewort (110-> 010). Für das Abändern einer Stelle in Kodewörtern der Länge 3 gibt es nur 3 Möglichkeiten, was mit der Würfelvorstellung wieder übereinstimmt.
Wie sieht€s mit Hammingkugeln mit Radius 2 aus?
Jetzt darf man sich bis zu 2 Kanten vom Ausgangspunkt wegbewegen oder anders formuliert: Man darf im Kodewort bis zu 2 Stellen abändern.
Wieviele Kodewörter können so erhalten werden?
Erstmal liegen die Kodewörter der Hammingkugel mit Radius 1 ganz in der Hammingkugel mit Radius 2, also kommen diese Kodewörter dazu, dies sind 1+3 = 4. So haben wir alle Kodewörter gezählt, bei denen bis zu einer Stelle des Ursprungswortes abgeändert wurde. Es verbleiben noch die Kodewörter, die man erhält, wenn man genau zwei Stellen des ursprünglichen Kodeworts verändert. Man hat 3 über 2 Möglichkeiten dieses zu tun, d.h. man erhält 3 über 2 = 3 Kodewörter, die sich in genau 2 Stellen vom Ausgangspunkt unterscheiden.
Zusammen sind das
        / 3 \   / 3 \   / 3 \
1+3+3 = (   ) + (   ) + (   )  = 7 Kodewörter in Hammingkugel mit Radius 2.
        \ 0 /   \ 1 /   \ 2 /

Allgemein kann man durch obige Anschauung daraufkommen, dass die Anzahl der Kodewörter in einer Hammingkugel mit Radius r um ein Kodewort A über einen binären Kode der Länge n gegeben ist durch:
    r
   ___  / n \
   \    (   )  = Anzahl der Kodewörter in Hammingkugel mit Radius r
   /__  \ i /
   i=0

Hamminggrenze: Ungleichung für efache Fehlerkorrektur

Zuerst wird nochmals die Ungleichung für einen Kode hergeleitet, der Einzelfehlerkorrektur zu läßt. Man hat einen binären Kode der Länge n=m+k; wobei m die Anzahl der Datenbits und k die Anzahl der Kontrollbits ist. Es gibt also 2^m gültige Kodewörter und 2^k ungültige Kodewörter.
Sendet man ein gültiges Kodewort X und tritt irgendwo ein einzelner Fehler auf, so befindet sich das tatsächlich empfangene Kodewort X', in der Hammingkugel mit dem Radius 1 um das gesendete Kodewort, da sich das empfangene Kodewort nur in einer Stelle vom ursprünglichen Kodewort unterscheidet und so nur den Hammingabstand 1 von ihm besitzt. Betrachtet man jetzt alle anderen Kodewörter Y und zieht jeweils eine Hammingkugel von Radius 1 um diese, so wäre es fatal, wenn das tatsächlich empfangene Kodewort X', in einer dieser anderen Hammingkugeln läge. Denn dann hätte man wenigstens zwei gültige Kodeworte X und Y, die sich nur um eine Stelle vom empfangenen Kodewort X€ unterscheiden. In so einer Situation kann man sich nicht entscheiden, was die bessere Wahl darstellt, da man zwei gleichwahrscheinlich richtige Kandidaten hat. Um dies zu vermeiden, dürfen sich die Hammingkugeln mit Radius 1 nicht überlappen.
Der Kode muß daher mindestens soviele Punkte besitzen wie in alle Hammingkugeln um die 2^m gültigen Kodewörter passen. Das ergibt
  n     m                m+k      m           k
 2  >= 2  * (n+1)  <=>  2     >= 2 (n+1) <=> 2  >= n+1. 
Genauso kann man dies für Doppelfehlerkorrektur herleiten:
  n      m          / n \          k          / n \
 2   >= 2  * (1+n+  (    ) ) <=>  2  >= (1+n+ (    ) )
                    \ 2 /                     \ 2 /
Allgemein gilt dann für efache Fehlerkorrektur:
     
          e                               e
  k      ___    / n \                    ___  / n \
 2   >=  \      (   )     bzw.  k >= ld( \    (   )  )
         /__    \ i /                    /__  \ i /
        i = 0                            i=0
Die Ungleichung rechts wird auch als Hamminggrenze bezeichnet.
Sie gibt an, wieviele Kontrollstellen mindestens nötig sind, um e Fehler korrigieren zu können. Es ist allerdings nicht gesagt,dass es einen Kode geben muß, der diese Ungleichung einmal genau erfüllt also zur Gleichung macht. Der weiter oben konstruierte Hammingkode für Einzelfehlerkorrektur erfüllt die Ungleichung auch nur dann genau, wenn die Kodewörter die Länge 2^l-1 haben.

Zusammenfassung

Diese Abhandlung ging auf die Grundlagen der Fehlererkennung/korrektur ein und versuchte folgende Dinge zu verdeutlichen: Schließlich bleibt noch darauf zu verweisen, dass Kodes, die die im vorletzten Punkt aufgeführten Eigenschaften besitzen, existieren und obendrein einfach zu implementieren sind. Für Einzelfehlerkorrektur ist der besprochene Hammingkode zu nennen und für einfache Einzelfehlererkennung die Paritätsprüfung.
Man muß bei der Anwendung solcher Verfahren immer Kosten und Nutzen gegenüber stellen, um eine klare Übersicht zu gewinnen. Entweder kann ein Verfahren wirklich das Gewünschte leisten oder Übervorsicht zu unvertretbaren Leistungseinbußen führen.
Bei einer solchen Analyse kann man den minimalen Hammingabstand des Kodes nutzen. Dieser stellt eine Mindestanforderung den Kode dar. Er gibt somit Auskunft darüber, ob dieser Kode vielleicht doch noch zu redundant ausgelegt ist, oder ob er manchmal das theoretisch Machbare streift und somit optimal ist.
Was hier nicht besprochen wurde ist die Restfehlerwahrscheinlichkeit redundanter Kodes. Dies ist gerade sehr wichtig, um den Nutzen eines Verfahrens einschätzen zu können. Daher sei auf die Literatur verwiesen.

Um abrundend noch einen geschichtlichen Aspekt einzuwerfen, sei noch angemerkt, dass der Hammingkode bzw. die Hamminggrenze von R. W. Hamming 1950 gefunden wurden. Hamming ist in diesem Jahr (1998) im Januar im Alter von 83 Jahren gestorben. Schlieśen mńchte ich mit einem Zitat Hammings:

The purpose of computing is insight, not numbers.

Literatur


Dirk Focken (Email: nekov@bigfoot.com) 10. Januar 1999