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)];

[Maple Math]

Dann definieren wir die Polynome c(x) und g(x),

> c := add( mc[i]*x^(i-1), i=1..nops(mc) );

[Maple Math]

> g:= 1: for i to 2*2 do g := PolyMal(g,x-Exp(alpha,i)) od: print(g);

[Maple Math]

berechnen

> d := PolyMal(c,g);

[Maple Math]

und extrahieren daraus die Werte d _i:

> md := [seq( coeff(d,x,i), i=0..degree(d,x))];

[Maple Math]

Empfangener Text: (enthält zwei Fehler!!)

> mf := [4,2,4,3,6,6,5];

[Maple Math]

Definiere das Polynom f(x)

> f := add( mf[i]*x^(i-1), i=1..nops(mf) );

[Maple Math]

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);

[Maple Math]

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);

[Maple Math]

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;

[Maple Math]

Nun können wir dd(x) rekonstruieren:

> dd := PolyPlus(f,e);

[Maple Math]

und daraus cc(x) = dd(x) / g(x) berechnen.

> cc := PolyDiv(dd,g);

[Maple Math]

Der decodierte Text besteht genau aus den Koeffizienten von cc(x):

> [ seq(coeff(cc,x,i),i=0..degree(cc,x))];

[Maple Math]

===> Und das ist wirklich der richtige Eingabetext...!!!