Beispiel: Reed-Solomon Code RS(3,3,2)
Jeder Block besteht also aus s=3 Bits (d.h, wir rechen in GF(8)),
und aus jeweils k=3 solcher Blöcke werden 3+2*2=7 Blöcke,
von denen bis zu t=2 in der Übertragung gestört werden dürfen.
Initialisierung:
Wir bringen Maple bei, daß wir in GF(8) rechnen wollen. Dabei wollen wir die Elemente von GF(8) mit den
Zahlen 0,1,...,7 bezeichnen.
> restart: readlib(GF):
> pi := z^3+z+1: K := GF(2,3,pi):
> Plus:= (a,b) -> K[output](K[`+`](K[input](a),K[input](b))):
> Mal:= (a,b) -> K[output](K[`*`](K[input](a),K[input](b))):
> Exp:= (a,k) -> K[output](K[`^`](K[input](a),k)):
> h1 := proc(f) local i; add(K[ConvertOut](K[input](coeff(f,x,i)))*x^i,i=0..degree(f,x)) end:
> h2 := proc(f) local i; add(K[output](K[ConvertIn](coeff(f,x,i)))*x^i,i=0..degree(f,x)) end:
> PolyPlus := (f,g) -> h2(Rem(h1(f) + h1(g), pi, z) mod 2):
> PolyMal := (f,g) -> h2(Rem(h1(f) * h1(g), pi, z) mod 2):
> PolyDiv := (f,g) -> h2(Rem( Quo(h1(f), h1(g),x) mod 2, pi, z) mod 2):
> PolyRest := (f,g) -> h2(Rem( Rem(h1(f), h1(g),x) mod 2, pi, z) mod 2):
> PolyF := (f,a) -> K[output](K[ConvertIn]( (Rem(subs(x=K[ConvertOut](K[input](a)),h1(f)), pi, z) mod 2))):
> alpha := 2:
Ab jetzt können wir in GF(8) wie folgt rechnen:
Plus(a,b), Mal(a,b): addiert bzw. multipliziert zwei Zahlen a und b,
Exp(a,k): berechnet die k-te Potenz von a,
PolyPlus(f,g), PolyMal(f,g), PolyDiv(f,g): addiert, multipliziert bzw. dividert zwei Polynome f,g
alpha bezeichnet ein primitives Element
Eingabetext:
> m := [1,1,0,0,1,1,1,0,1]:
Den Text zerlegen wir in k=3 Blöcke mit jeweils s=3 Bits und fassen jeden Block als Zahl in GF(8) auf:
> mc := [seq( m[3*i-2]*4+m[3*i-1]*2+m[3*i], i=1..nops(m)/3)];
Dann definieren wir die Polynome c(x) und g(x),
> c := add( mc[i]*x^(i-1), i=1..nops(mc) );
> g:= 1: for i to 2*2 do g := PolyMal(g,x-Exp(alpha,i)) od: print(g);
berechnen
> d := PolyMal(c,g);
und extrahieren daraus die Werte d _i:
> md := [seq( coeff(d,x,i), i=0..degree(d,x))];
Empfangener Text: (enthält zwei Fehler!!)
> mf := [4,2,4,3,6,6,5];
Definiere das Polynom f(x)
> f := add( mf[i]*x^(i-1), i=1..nops(mf) );
und werte es an den Stellen alpha^i, i=1..2*t , aus:
>
fa := array(1..4):
for i to 4 do fa[i] := PolyF(f, Exp(alpha,i)) od:
print(fa);
Falls keine Übertragungsfehler aufgetreten wären, wäre fa identisch Null.
Es sind also Fehler aufgetreten: Diese werden wir jetzt beseitigen.
Dazu bestimmen wir zunächst den Rest von f(x) modulo g(x):
> f_g := PolyRest(f,g);
und suchen dann einen Repräsentanten dieser Restklasse bei dem möglichst wenige
Koeffizienten von Null verschieden sind. Dazu betrachten wir
f_g + (i*x + j) * g(x) für alle i,j aus GF(8)
Wir wissen: Gab es höchstens zwei Übertragungsfehler so hat genau eines dieser Polynome höchstens 2 von Null
verschieden Koeffizienten. Dieses bildet das Fehlerpolynom e(x):
> for i from 0 to 7 do
> for j from 0 to 7 do
> h := PolyPlus(f_g, PolyMal(i*x+j,g));
> hc := 0; for ii from 0 to degree(h,x) do
> if coeff(h,x,ii) > 0 then hc := hc + 1 fi; od;
> if hc <= 2 then e:= h; print(e) fi;
> od;
> od;
Nun können wir dd(x) rekonstruieren:
> dd := PolyPlus(f,e);
und daraus cc(x) = dd(x) / g(x) berechnen.
> cc := PolyDiv(dd,g);
Der decodierte Text besteht genau aus den Koeffizienten von cc(x):
> [ seq(coeff(cc,x,i),i=0..degree(cc,x))];
===> Und das ist wirklich der richtige Eingabetext...!!!