Corriger des erreurs
Renaud Rioboo
Projet Groupe 1.1
Contexte
L’informatique manipule d’une mani`ere ou d’une autre des suites de bits qui
doivent ˆetre trait´es exactement. Une erreur inversant un bit change compl`etement
le sens de la suite et on essaie d’´eviter ces erreurs en ajoutant de la redondance
aux donn´ees pour pouvoir les d´etecter voire les corriger.
La technique la plus connue est celle du bit de parit´e o`u on code kbits
b1,...bken ajoutant un bit bk+1 de fa¸con `a ce que la somme des k+ 1 bits `a un
soit paire.
Si une erreur a affect´e la suite (bi)i=k+1
i=1 lors d’une transmission ou d’une
´ecriture sur un support physqique on re¸coit une suite (b0
i)i=k+1
i=1 dont la parit´e
est fausse. Si par contre aucune erreur n’a eu lieu la parit´e est bonne. Dans le
cas de deux erreurs ou plus on ne peut bien sur rien dire.
Un tel codage est dit d´etecteur d’une erreur sur un bloc de k+ 1 bits. Un
code qui corrigerait une erreur serait dit correcteur d’une erreur.
Pour formaliser cette technique on se place dans le corps `a deux ´el´ements F2
et on a
Σi=k+!
i=1 bi= 0
En g´en´eral on interpr`ete la suite (b0
i)i=k+1
i=1 comme le polynˆome P(X) =
Σi=k+1
i=1 biXk+1iet l’´equation devient simplement P(1) = 0 dans F2[X] l’ensemble
des polynˆomes `a coefficients sur F2. Ceci revient `a dire que le polynˆome Pest
divible par X1 (qui vaut aussi X+ 1 dans F2[X]).
Plus g´en´eralement les codes dits cycliques encore appel´es CRC (Cyclic Re-
dundancy Check) permettent de d´etecter et de corriger plus d’une erreur et sont
utilis´es dans tous les supports modernes de donn´ees. Le code est alors form´e
de l’ensemble des multiples d’un polynˆome g´en´erateur Pc. Ces codes sont dits
cycliques car Pcest un diviseur de XN1 pour un certain N.
On se fixe donc un polynˆome de test Pcde degr´e ket, pour coder un
polynˆome Pu, on calcule Rde degr´e inf´erieur `a k1 pour que Pe=XkPu+R
soit mulitple de Pc. Ainsi Rest le reste de la division Euclidienne de XkPupar
Pc. Pour tester si un polynˆome Pest dans le code il nous suffit de calculer le
reste de la division Euclidienne de Ppar Pcet si ce reste est nul on tronque les
kderniers bits.
1
Le Travail
Notre but est d’impl´ementer une librairie de polynˆomes pour effectuer la division
Euclidienne des polynˆomes.
Vous devrez rendre sur le serveur de d´epˆots une archive contenant vos sources
et un rapport au format pdf expliquant vos choix d’impl´ementation ainsi que
les algorithmes utilis´es.
Bien que pour ce sujet nous n’utiliserons que des polynˆomes de F2[X] les
CRC utilis´es en pratique travaillent dans F256[X] o`u les coefficients sont dans le
corps `a 256 ´el´ements. Nous voulons avoir un code g´en´erique o`u les algorithmes
sur les polynˆomes peuvent s’exprimer sur n’importe quel corps de coefficients.
Les Nombres
Le corps F2contient les deux ´el´ements 0 et 1, nous utiliserons des entiers pour
les repr´esenter. Nous devons donc d´efinir un type de donn´ees Field ainsi que
des op´erations de base pour l’arithm´etique, les tests et l’impression.
Les Polynˆomes
Traditionellement les polynˆomes sont repr´esenes par des listes de monˆomes
qui sont des couples form´es d’un degr´e et d’un coefficient. Le degr´e est en
g´en´eral un entier non sign´e et le coefficient un ´el´ement non nul d’un anneau K
dont les valeurs peuvent ˆetre repr´esent´es de diff´erentes fa¸cons. Les listes sont
implicitement tri´ees par ordre d´ecroissant des monˆomes, c’est-`a-dire que les plus
hauts degr´es sont au d´ebut de la liste.
0.0.1 Addition et soustraction
´
Etant donn´es deux polynˆomes Pet Q, il vient de la repr´esentation que si Pet
Qsont non nuls ils se d´ecomposent en:
P=cpXdp+P0
Q=cqXdq+Q0
o`u cpet cqsont non nuls dans Ksans calculs.
La somme Sdes polynˆomes P+Qpeut donc se calculer par l’une des for-
mules: S=cpXdp+ (P0+Q)
S=cqXdq+ (P+Q0)
S=cXd+ (P0+Q0)
avec c=cp+cqet d=dp=dqet en fonction de la comparaison entre dpet dq.
Ici la somme cp+cqs’effectue bien sˆur dans K.
Dans la formule pr´ec´edente seule la somme P0+Q0est r´ecursive. On prendra
en outre soin de ne pas construire le monˆome cXdlorsque cest nul dans K.
L’algorithme est donc le mˆeme que celui qu’on applique `a la main et la
soustraction de fait de la mˆeme mani`ere.
2
1 Multiplication
Il n’est pas n´ecessaire de coder la multiplication pour la division Euclidienne
mais il vous est quand mˆeme demand´e de le faire. On proc`ede comme `a la main
et on d´ecompose deux polynˆomes Pet Qen:
P=cpXdp+P0
Q=cqXdq+Q0
comme plus haut. La multiplication consiste `a calculer le produit MqPo`u Mq
est le monˆome cqXdqlorsque Qest non nul.
Le produit MqPest nul si Pest nul. Sinon on l’exprime r´ecursivement en
fonction du produit MqP0et de c=cpcq:
cXdp+dq+MqP0.
La Division Euclidienne
Pour un polynˆome Aet un polynˆome non nul B, la division Euclidienne de A
par Bconsiste `a calculer un quotient Qet un reste Rtels que
A=BQ +R
o`u Rest nul ou de degr´e strictement inf´erieur celui de B. On d´ecompose
A=caXda+A0
B=cbXdb+B0
et le premier monˆome du quotient est ca/cbXdadb. Il suffit ensuite de proc´eder
r´ecursivement.
2 Mise en œuvre
Le fichier crc.c suivant vous propose quelques notations pour vous aider:
/* Cyclic codes */
#include <stdlib.h>
#include <stdio.h>
#define Field int
typedef struct p_data{
Field coef;
int deg;
struct p_data* red;} p_val;
typedef p_val* Poly;
3
// fonctions du corps de base
Field base_add(Field x, Field y) {return((x == y)? 0: 1);};
// On peut remarquer que modulo 2 + et - sont la m^eme operation
Field base_sub(Field x, Field y) {return((x == y)? 0: 1);};
Field base_mult(Field x, Field y) {return(x? y: x);};
int base_is_zero(Field x) {return(x);};
void base_print(Field x) {printf("%d", x);};
Field base_zero = 0;
Field base_one = 1;
// la valeur polynomiale 0
Poly poly_zero = NULL;
//quelques fonctions a implanter
Poly poly_add(Poly p1, Poly p2) {return(NULL);};
Poly poly_sub(Poly p1, Poly p2) {return(NULL);};
Poly poly_mult(Poly p1, Poly p2) {return(NULL);};
// ring_to_poly(v) suppose que v n’est pas nul dans l’anneau. fixme!
Poly ring_to_poly(Field v) {
p_val* temp = malloc(sizeof(p_val));
temp->coef = v;
temp->deg = 0;
temp->red = poly_zero;
return(temp);
}
int main(){
return((ring_to_poly(base_one))->deg);
}
4
1 / 4 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !