CODES BCH

Le but de cette feuille est de fabriquer un code BCH (binaire primitif), et de faire tourner son algorithme de décodage basé sur l'algorithme d'Euclide. La référence recommandée est le livre de Demazure : Cours d'algèbre, éditions Cassini, chapitre 9.
Tous les calculs se font mod 2. Il est conseillé de consulter l'aide de Maple sur "mod" si l'on ne sait pas comment ça fonctionne.

>    restart:

Création du code. Corps engendré par les racines n -èmes de l'unité sur F _2

On fixe la longueur n  du code. L'entier n  est de la forme 2^ r -1.

Choisir r  pour fixer la longueur n  du code .

>    r:= 7: n:=2^r-1;

n := 127

Un mot   a_ 1 ...a_n (codé comme un liste) est identifié  à l' élément du quotient F _2[ X ]/( X ^ n -1) représenté par le polynome
a _1 X ^{ n  -1} + ... + a _ n  (N.B. :  Demazure écrit le polynome dans l'ordre des puissances croissantes).
Deux procédures tres simples permettent de passer du mot au polynome et vice-versa.

>    Pol:=proc(M,n,X)
local k;
add(M[k]*X^(n-k), k=1..n);
end;

Pol := proc (M, n, X) local k; add(M[k]*X^(n-k),k = 1 .. n) end proc

>    Mot:=proc(P,n,X)
local i;
[seq(coeff(P,X,n-i),i=1..n)];
end;

Mot := proc (P, n, X) local i; [seq(coeff(P,X,n-i),i = 1 .. n)] end proc

Le polynome X ^ n  -1 se décompose sur le corps F _{2^ r }, dont le groupe multiplicatif est celui des racines n -èmes de l'unite. Les calculs de décodage vont se faire dans  ce corps F _{2^ r }. Pour pouvoir calculer,  on va choisir un élément primitif alpha  (une racine primitive n -ème de l'unite). Le polynome minimal de alpha  est un facteur irréductible du polynome cyclotomique Phi_n  sur F _2, forcément de degré   r . On produit d'abord la liste de tous les facteurs irréductibles de   Phi_n  sur F _2

>    Prim:=[op(Factor(numtheory[cyclotomic](n,X)) mod 2)];

Prim := [X^7+X^6+X^5+X^4+1, X^7+X^6+X^5+X^4+X^2+X+1, X^7+X+1, X^7+X^5+X^3+X+1, X^7+X^6+X^5+X^2+1, X^7+X^5+X^4+X^3+1, X^7+X^6+X^4+X^2+1, X^7+X^6+X^4+X+1, X^7+X^6+1, X^7+X^6+X^3+X+1, X^7+X^5+X^4+X^3+X^2+...
Prim := [X^7+X^6+X^5+X^4+1, X^7+X^6+X^5+X^4+X^2+X+1, X^7+X+1, X^7+X^5+X^3+X+1, X^7+X^6+X^5+X^2+1, X^7+X^5+X^4+X^3+1, X^7+X^6+X^4+X^2+1, X^7+X^6+X^4+X+1, X^7+X^6+1, X^7+X^6+X^3+X+1, X^7+X^5+X^4+X^3+X^2+...
Prim := [X^7+X^6+X^5+X^4+1, X^7+X^6+X^5+X^4+X^2+X+1, X^7+X+1, X^7+X^5+X^3+X+1, X^7+X^6+X^5+X^2+1, X^7+X^5+X^4+X^3+1, X^7+X^6+X^4+X^2+1, X^7+X^6+X^4+X+1, X^7+X^6+1, X^7+X^6+X^3+X+1, X^7+X^5+X^4+X^3+X^2+...
Prim := [X^7+X^6+X^5+X^4+1, X^7+X^6+X^5+X^4+X^2+X+1, X^7+X+1, X^7+X^5+X^3+X+1, X^7+X^6+X^5+X^2+1, X^7+X^5+X^4+X^3+1, X^7+X^6+X^4+X^2+1, X^7+X^6+X^4+X+1, X^7+X^6+1, X^7+X^6+X^3+X+1, X^7+X^5+X^4+X^3+X^2+...

On choisit un facteur P  de degré r  dans la liste

Choisir P  (le polynome minimal de alpha ) . La procédure suivante choisit un P  avec un nombre minimum de termes de façon  à alléger les calculs.

>    P:=Prim[1]:
for i from 2 to nops(Prim) do
if nops(Prim[i])<nops(P)then P:= Prim[i] fi
od: P;

X^7+X+1

On définit alpha  comme racine de P .

>    alias(alpha=RootOf(P));

alpha

On fixe maintenant la capacité de correction t  du code BCH (il sera de distance minimum prescrite 2 t +1).
Choisir t  pour fixer la capacité  de correction  du code .

>    t:=5;

t := 5

Par définition, un polynme C  appartiendra au code si et seulement si   C ( alpha ^ i )=0 pour i =1,...,2 t . On écrit une procédure qui calcule le polynme générateur du code. C'est le pgcd des polynomes minimaux sur F _2  des alpha ^ i  avec i  entre 1 et 2 t . On calcule l'ensemble des facteurs irréductibles de X ^ n  -1  pour trouver dedans le polynome minimal de alpha ^ i  avec i  entre 3 et 2 t . Pouvez-vous expliquer pourquoi on fait des pas de 2 dans la procédure suivante ? (Se souvenir que si beta est racine d'un polynome  à  coefficients dans F _2, alors beta ^2 l'est aussi.)

>    Generateur:=proc(alpha,t,X)
local G, SH, f, i ;
G:= subs(_Z=X,op(alpha)): #recupere le polynome minimal de alpha
SH:={op(Factor(X^n-1) mod 2)} minus {G}:
if t>1 then
for i from 3 by 2 to 2*t-1 do
for f in SH  do if Eval(f,X=alpha^i) mod 2 = 0
then G:=G*f : SH:=SH minus {f} : break fi od
od
fi:
Expand(G) mod 2;
end;

Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...
Generateur := proc (alpha, t, X) local G, SH, f, i; G := subs(_Z = X,op(alpha)); SH := `minus`({op(`mod`(Factor(X^n-1),2))},{G}); if 1 < t then for i from 3 by 2 to 2*t-1 do for f in SH while true do i...

Et voici le polynome générateur du code, et la dimension d  du code

>    G:=sort(Generateur(alpha,t,X)); d:= n-degree(G,X);

G := X^35+X^34+X^33+X^28+X^24+X^23+X^22+X^19+X^17+X^15+X^12+X^11+X^9+X^8+X^6+X^4+X^2+X+1

d := 92

Décodage par l'algorithme d'Euclide

Nous allons maintenant écrire les procédures de l'algorithme de décodage.

On commence par calculer le "polynome syndrome" d'un mot recu  R  de longueur n . C'est le polynome

S _1 + S _2 Z  +...+ S _{2 t } Z ^{2 t -1}, où S _ i  = R ( alpha ^ i ).

>    Syndi:=proc(P,i,alpha)
local beta;
beta:=Normal(alpha^i) mod 2:
Eval(P, X=beta) mod 2;
end;

Syndi := proc (P, i, alpha) local beta; beta := `mod`(Normal(alpha^i),2); `mod`(Eval(P,X = beta),2) end proc

>    Syndrome:=proc(R,alpha,t,n,X,Z)
local i,P;
P:=Pol(R,n,X):
add(Syndi(P,i,alpha)*Z^(i-1), i=1..(2*t))
end;

Syndrome := proc (R, alpha, t, n, X, Z) local i, P; P := Pol(R,n,X); add(Syndi(P,i,alpha)*Z^(i-1),i = 1 .. 2*t) end proc

On calcule ensuite le polynome localisateur d'erreurs à partir du polynome syndrome S , en utilisant l'algorithme d'Euclide avec
P_
0 =  Z ^{2 t } et P_ 1  = S et en s'arrétant dès que le degré du reste P_i est plus petit que   t.  C'est l'algorithme d'Euclide "semi-étendu": ce qu'on cherche est le B_i dans
P_i = A_i * Z ^{2 t } + B_i * S  . Il est donc inutile de calculer A_i.  Le vrai polynome localisateur d'erreurs est B_i  / B_i (0) (voir Demazure), mais il est inutile de diviser par la constante B_i  (0) puisqu'on ne s'intéressera  qu'aux racines du polynome localisateur d'erreurs.

>    Localisateur:=proc(S,t,Z)
local P, Q, R, BB, B, C;
P:=Z^(2*t): Q:=S: BB:=0: B:= 1:
while degree(Q,Z) >= t
do C:=BB-B*Quo(P,Q,Z) mod 2 : R:=Rem(P,Q,Z) mod 2:
P:=Q: Q:=R: BB:=B: B:=C:
od:
Normal(collect(B,Z)) mod 2;
end;

Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...
Localisateur := proc (S, t, Z) local P, Q, R, BB, B, C; P := Z^(2*t); Q := S; BB := 0; B := 1;  while t <= degree(Q,Z) do C := `mod`(BB-B*Quo(P,Q,Z),2); R := `mod`(Rem(P,Q,Z),2); P := Q; Q := R; BB := ...

Enfin, la procédure suivante permet de retrouver le vecteur d'erreur  à partir du polynome localisateur. Le bit r_i  du mot recu R  est erroné si et seulement si alpha ^ i  est racine du polynome localisateur d'erreurs. (Si on suit le livre de Demazure, ca serait si et seulement si alpha ^(- i ) est racine; c'est parce que, contrairement  à ce qui est fait ici, Demazure identifie un mot  avec un polynome écrit dans le sens des puissances croissantes.)

>    Testz:=proc(L,i,alpha,Z)
if Eval(L, Z=alpha^i) mod 2 =0 then 1 else 0 fi;
end;

Testz := proc (L, i, alpha, Z) if `mod`(Eval(L,Z = alpha^i),2) = 0 then 1 else 0 end if end proc

>    Erreur:=proc(L,alpha,n,Z)
local i;
[seq(Testz(L,i,alpha,Z),i=1..n)]
end;

Erreur := proc (L, alpha, n, Z) local i; [seq(Testz(L,i,alpha,Z),i = 1 .. n)] end proc

Essais

On va passer  a des essais. On écrit un générateur de mots de code au hasard. On multiplie le polynome générateur G  par un polynome au hasard de degré < d (la dimension du code).

>    Motcode:=proc(G,n,X)
local CC, d;
d:= n-degree(G,X):
CC:=Expand((Randpoly(d-1,X) mod 2) * G) mod 2:
Mot(CC,n,X);
end;

Motcode := proc (G, n, X) local CC, d; d := n-degree(G,X); CC := `mod`(Expand(`mod`(Randpoly(d-1,X),2)*G),2); Mot(CC,n,X) end proc
Motcode := proc (G, n, X) local CC, d; d := n-degree(G,X); CC := `mod`(Expand(`mod`(Randpoly(d-1,X),2)*G),2); Mot(CC,n,X) end proc
Motcode := proc (G, n, X) local CC, d; d := n-degree(G,X); CC := `mod`(Expand(`mod`(Randpoly(d-1,X),2)*G),2); Mot(CC,n,X) end proc
Motcode := proc (G, n, X) local CC, d; d := n-degree(G,X); CC := `mod`(Expand(`mod`(Randpoly(d-1,X),2)*G),2); Mot(CC,n,X) end proc

On écrit  un générateur de vecteur d'erreur aléatoire, en fonction d'un  nombre d'erreurs NE. (Le nombre réel d'erreur peut etre moindre si l'on tire au hasard deux fois la meme position d'erreur).

>    Bruit:=proc(NE,n,X)
local BB, EXP, i;
EXP:=rand(0..(n-1)):
BB:=add(X^EXP(),i=1..NE) mod 2:
Mot(BB,n,X);
end;

Bruit := proc (NE, n, X) local BB, EXP, i; EXP := rand(0 .. n-1); BB := `mod`(add(X^EXP(),i = 1 .. NE),2); Mot(BB,n,X) end proc
Bruit := proc (NE, n, X) local BB, EXP, i; EXP := rand(0 .. n-1); BB := `mod`(add(X^EXP(),i = 1 .. NE),2); Mot(BB,n,X) end proc

Choisir le nombre d'erreurs NE.

>    NE:=5;

NE := 5

Maintenant on expérimente : on génère un mot de code C au hasard, on y ajoute une erreur aléatoire B, et on passe au décodage. Normalement, si le poids du "bruit" B ajouté lors de la transmission est <= t, le décodage est correct.

>    C:= Motcode(G,n,X);
B:= Bruit(NE,n,X);
R:=C+B mod 2;
S:=Syndrome(R,alpha,t,n,X,Z);
L:=Localisateur(S,t,Z);
ERR:=Erreur(L,alpha,n,Z);
DECODE:=R+ERR mod 2;
evalb(C=DECODE);

C := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, ...
C := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, ...
C := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, ...

B := [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
B := [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
B := [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...

R := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, ...
R := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, ...
R := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, ...

S := alpha^3+alpha^2+1+(alpha^6+alpha^4+1)*Z+(alpha^6+alpha^5+alpha^4+alpha+1)*Z^2+(alpha^6+alpha^5+alpha^2+alpha+1)*Z^3+alpha^6*Z^4+(alpha^6+alpha^5+alpha^4+alpha^3+alpha+1)*Z^5+(alpha^3+alpha+1)*Z^6+...
S := alpha^3+alpha^2+1+(alpha^6+alpha^4+1)*Z+(alpha^6+alpha^5+alpha^4+alpha+1)*Z^2+(alpha^6+alpha^5+alpha^2+alpha+1)*Z^3+alpha^6*Z^4+(alpha^6+alpha^5+alpha^4+alpha^3+alpha+1)*Z^5+(alpha^3+alpha+1)*Z^6+...
S := alpha^3+alpha^2+1+(alpha^6+alpha^4+1)*Z+(alpha^6+alpha^5+alpha^4+alpha+1)*Z^2+(alpha^6+alpha^5+alpha^2+alpha+1)*Z^3+alpha^6*Z^4+(alpha^6+alpha^5+alpha^4+alpha^3+alpha+1)*Z^5+(alpha^3+alpha+1)*Z^6+...

L := (alpha^6+alpha^4+alpha^3+alpha)*(Z^5+(alpha^5+alpha)*Z^4+(alpha^6+alpha^5+alpha^4+alpha^2+alpha+1)*Z^3+(alpha^3+alpha)*Z^2+(alpha^6+alpha^5+1)*Z+alpha^5+alpha^4+alpha+1)
L := (alpha^6+alpha^4+alpha^3+alpha)*(Z^5+(alpha^5+alpha)*Z^4+(alpha^6+alpha^5+alpha^4+alpha^2+alpha+1)*Z^3+(alpha^3+alpha)*Z^2+(alpha^6+alpha^5+1)*Z+alpha^5+alpha^4+alpha+1)

ERR := [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
ERR := [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
ERR := [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...

DECODE := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1...
DECODE := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1...
DECODE := [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1...

true

>