Cours sur les codes correcteurs



CODES CORRECTEURS

1. Encodeurs

1.1. Distance de Hamming

1.2. Poids de Hamming

1.3. Codes en blocs - linéaires

1.3.1. Matrice génératrice

1.3.2. Matrice de contrôle

1.4. Codes systématiques

Si la première moitié du vingtième siècle a été celle de la révolution analogique par la radio et la télévision, la seconde moitié de ce siècle est celle de la révolution numérique et de l'utilisation systématique de l'algèbre dans la transmission de données.

Ainsi, après l'apparition du CD audio dans les années 1980, il faut compter sur le développement de la diffusion par satellite de nouveaux moyens de communication tels la télécopie, le réseau Internet ou le téléphone numérique. Les données (textes, images et sons) sont maintenant engrangées sur des CD-ROM dont les lecteurs sont munis de systèmes de codes correcteurs d'erreurs (C.C.D.). Même la photographie et la radio deviennent par ailleurs numériques.

Les techniques de restitution d'images ou de sons sont liées à la transmission et à la lecture correcte de nombreux messages numériques, encore appelés "mots". Un message est formé de mots, eux-mêmes constituées de symboles (un exemple particulier étant le "bit") pris dans un alphabet. Si l'aphabet est binaire alors chaque symbole sera donc un bit.

Prenons le message 00101 formé de 5 bits valant chacun 0 ou 1. Si nous transmettons le message tel quel, une erreur de transmission ou de lecture peut avoir lieu et rendre le message inintelligible. Décidons de répéter ce message trois fois et d'envoyer :

001010010100101   (1)

Si le message reçu comporte une erreur, cette erreur peut être corrigée. S'il comporte deux erreurs, le récepteur est capable de détecter qu'il y a eu erreur mais ne peut pas toujours récupérer le message originel. Enfin, s'il se produit plus de deux erreurs pendant la transmission, le récepteur peut ne pas les détecter.

Nous venons ainsi de voir un premier exemple de C.C.D., appelé "code à répétition". Ce code, qui corrige une erreur et en détecte deux, est utilisé dans certains lecteurs de CD Audio possédant trois têtes de lecteur. Le signal 0 ou 1 est lu indépendamment par chacun de ces trois têtes pour donner un mot de trois chiffres, et une erreur de lecture peut être corrigée.

Remarquons qu'il est naturel d'allonger un message pour le protéger. Prenons les mots d'un langage. Ils sont en général très éloignés les uns des autres, deux mots différant selon leur longueurs et selon les lettres et les syllabe utilisées. Ainsi, nous confondrons difficilement les mots "bibliothèque" et "armoire" même si ces mots sont mal prononcés ou entendus, et nous reconstituerons naturellement le message dans une conversation quand bien même certains sons seraient supprimés ou déformés. Les militaires quant à eux épèlent leurs numéros d'immatriculation en disant "alpha zoulou" pour "AZ"...

Un deuxième exemple de détection d'erreurs largement utilisé en informatique est l'adjonction d'un "bit de parité". Reprenons le message 00101 et ajoutons lui un dernier bit obtenu en additionnant les cinq bits du départ modulo 2. Le message devient 001010 et permet de détecter une erreur sans toutefois pouvoir la corriger. Pour cela, nous faisons la somme de tous les bits pour obtenir 0 s'il n'y a pas eu d'erreur, et 1 dans le cas contraire. Ce code appelé "code parité", est utilisé un peu partout : dans les numéros de sécurité sociale où l'on rajoute la clé, dans ceux des comptes bancaires ou encore dans les code-barres des supermarchés où c'est le 13ème chiffre qui constitue la clé de contrôle (Voyager II est un des nombreux utilisateurs des codes de parité pour communiquer de manière fiable ainsi que le 8ème bit de l'ASCII qui est utilisé comme bit de parité).

Pendant de nombreuses années, les boîtiers de DRAM géraient des mots d'un bit ; il fallait donc placer sur la carte mémoire 8 boîtiers pour travailler avec des octets (8 bits). Pourtant, de nombreuses cartes comportaient non pas 8, mais 9 boîtiers ! Le neuvième boîtier était destiné à stocker un bit de parité lors de chaque mise en mémoire d'un octet. Lors de la lecture d'un octet, on vérifiait si, entre le moment de l'écriture et celui de la lecture, la parité n'avait pas été modifiée (suite à un parasite, par exemple).

equation
  (2)

Enfin, voyons un troisième exemple utilisé sur certains serveurs informatiques qui utilisent des disques parallèles en RAID4 ou RAID6 dont ce dernier utilise les codes de Hamming que nous verrons plus loin.

Supposons que nous ayons trois disques durs de données, et que le contenu du premier octet de chaque disque soit le suivant:

equation   (3)

Alors il suffit de prendre chaque colonne est de compter le nombre p de 1 dans la colonne. La valeur du bit de parité est alors p modulo 2. Nous avons pour la première colonne p qui vaut 2. Donc le bit de parité vaut 0, etc. Nous avons alors sur le disque de contrôle DC:

equation   (4)

Dès lors, dès qu'un des trois disques tombe en panne il devient aisé de le restaurer grâce au disque de contrôle en faisant la procédure inverse.

Ces trois exemples fondamentaux sont à la base de la théorie du codage et montrent que nous pouvons maîtriser l'apparition d'erreur en allongeant volontairement le message avant sa transmission ou sa lecture. Des techniques algébriques plus sophistiquées sont ensuite utilisées pour améliorer les performances du codage, le but étant :

- De savoir si des erreurs se sont produites (problème de la détection)

- De retrouver le message correct à partir du message reçu (problème de la correction)

- De corriger le plus d'erreurs possibles tout en utilisant le moins de bits supplémentaires possibles (problème de la performance du codage).

Du point de vue mathématique, l'un des intérêts de la théorie des codes est de montrer que l'algèbre s'applique fondamentalement dans notre vie de tous le jours dès que nous écoutons de la musique ou que nous nous installions devant notre téléviseur, et que des notions aussi abstraites que celles d'espaces vectoriels ou de polynômes sur des corps finis nous permettent de lire des message, d'écouter de la musique ou de regarder des films dans des conditions optimum.

Nous distinguons les deux classes suivantes de C.C.D. : les codes en blocs et les codes en treillis. La figure ci-dessous donne un simple résumé de la grande famille de codage. Dans la première classe (à droite sur la figure), citons les codes les plus célèbres comme les codes BCH, Reed-Solomon et Goppa, Golay et Hamming. La deuxième classe (à gauche sur la figure) est moins riche en variété mais présente beaucoup plus de souplesse surtout dans le choix des paramètres et des algorithmes de décodage disponibles. Citons par exemple, les codes convolutifs binaires systématiques récursifs très utilisés dans les modulations codées (TCM) et les codes concaténés parallèles (Turbo Codes).

equation
  (5)

Remarque: Pour aborder les fondements de la théorie des codes correcteurs, nous conseillons au lecteur d'avoir parcouru au préalable les chapitres de mécanique statistique (où se trouve la théorie de l'information), des systèmes numériques formels, et de topologie.

CHECKSUM

Avant de commencer dans la partie de mathématiques pures, nous souhaiterions faire une petite introduction sur le"checksum" (somme de contrôle) qui est un outil très fréquemment utilisé dans les entreprises lors de l'échange de fichier de plus de quelques GB entre deux ordinateurs ou encore lors du téléchargement sur Internet.

La somme de contrôle, parfois appelé aussi "empreinte", est un concept de base de la théorie des codes utilisé pour les codes correcteurs, elle correspond à un cas particulier de contrôle par redondance. Elle est largement utilisée en informatique et en télécommunications numériques.

Les codes utilisant les sommes de contrôle permettent de valider un message. Si le nombre d'altérations durant la transmission est suffisamment petit, alors elles sont détectées. L'utilisation d'une unique somme de contrôle permet la détection mais non la correction des erreurs.

La technique de base consiste à prendre la somme de certaines longeurs de bits (octets, word ou autre...) et de calculer leur module 255 (FF). Par exemple:

equation
  (Eq.6) Source Wikipedia

Certains utilisent aussi le MD5 (Message Digest 5) pour avoir une empreinte d'un message (cf. chapitre de Cryptographie).

ENCODEURS

Soit Q un ensemble fini à q éléments (bits, alphabets). Soient k et n deux entiers naturels non nuls avec equation. L'ensemble des messages sera une partie E de equation, et nous introduisons une application bijective (du moins c'est le but) :

equation   (Eq.7)  

appelée "application de codage" ou "encodeur". Le message ou mot a est un élément de E. Il est modifié pour fournir le mot equation. C'est le mot c qui sera transmis et lu par un système quelconque pour donner un message reçu equation éventuellement entaché d'erreurs.

Notons equation l'image de f. Comme f est injective, f réalise une bijection de E sur C et C peut être considéré comme l'ensemble de tous les messages possibles. C est appelé "code de longueur n", et les éléments de C s'appellent les "mots" du code. Le cardinal du code est par définition celui de C. Nous le noterons #C ou M. Pour mesurer le degré de différence entre deux mots x et y de equation, nous utilisons la distance de Hamming d définie par :

equation   (Eq.8)

Démonstration:

Sur un ensemble Q quelconque nous définissons donc l'application equation par :

equation   (Eq.9)

Si nous notons par equation la fonction caractéristique de x:

equation   (Eq.10)

alors :

equation   (Eq.11)

Montrons que d est une distance (cf. chapitre de Topologie) :

1. Il sera supposé que :

equation   (Eq.12)

est évident.

2. Il sera supposé que :

equation   (Eq.13)

est évident aussi.

3. Il sera supposé que :

equation   (Eq.14)

est évident aussi.

4. Nous avons aussi :

equation   (Eq.15)

equation signifie que equation pour equation donc que equation.

5. Enfin :

equation   (Eq.16)

En effet :

equation   (Eq.17)

mais comme :

equation   (Eq.18)

car equation vaut 1 si equation et 0 sinon, alors :

equation   (Eq.19)

equationC.Q.F.D.

Remarque: Attention les vecteurs seront notés sans la flèche par respect de la tradition dans ce cadre d'étude.

La distance de Hamming (notée equation dans certains ouvrages) est bien une métrique (cf. chapitre de Topologie) comme nous venons de le démontrer et nous appelons alors "espace de Hamming" sur Q l'ensemble equation muni de la métrique equation.

Définition: Si Q est un groupe, le "poids de Hamming" equation d'un mot equation est le nombre de ses coordonnées non nulles :

equation   (Eq.20)

où 0 est le mot (vecteur) de equation ayant toutes ses coordonnées égales à l'élément neutre de Q. Nous avons par ailleurs la propriété triviale suivante :

equation   (Eq.21)

Remarque: Lorsque equation nous parlerons de "code binaire" (nous allons voir de suite plus loin une autre forme d'écriture pour cet ensemble binaire) de dimension n égal à 2.

La "distance minimale" du code C est la distance minimum entre deux mots distincts de ce code. Nous notons ce nombre entier d(C) ou simplement d et donc :

equation   (Eq.22)

ou encore en utilisant la propriété du poids de Hamming equation:

equation   (Eq.23)

Définitions:

D1. Un code C de longueur n, de cardinal M et de distance minimale d est appelé "code (n,M,d)". Les nombres n, M, d sont les "paramètres du code".

D2. Nous appelons "poids minimum" d'un code C l'entier :

equation   (Eq.24)

d jour un rôle important car il se trouve en relation étroite avec le nombre d'erreurs susceptibles d'être corrigées. Supposons que le message codé soit equation et qu'il y ait eu moins de e erreurs de transmission ou de lecture. Le message obtenu equation vérifie equation. Nous pouvons retrouver c à partir de x set, et seulement si, il existe un seul mot de code situé à une distance de x inférieure ou égale à e (donc que la distance centre à centre entre deux boules soit égale à 2e). Autrement dit, il faut et il suffit que les boules fermées de rayon e et centrées sur les éléments du code C soient disjointes. Un code corrigera e erreurs si cette condition est vérifiée.

Ainsi, un code C de distance minimale d corrige au plus :

equation   (Eq.25)

erreurs (où [ ] représente la partie entière d'un nombre réel).

Effectivement, si un message du code se trouve à d/2 nous ne pourrons savoir à quel message du code (centre de boule) il appartient puisque se trouvant (de manière imagée) à la tangente de deux boules. C'est la raison pour laquelle nous prendrons equation qui représente alors la "distance sûre" et pour corriger au mieux un message erroné du code. De plus, comme le nombre d'erreur est un entier il vient naturellement l'écriture :

equation   (Eq.26)

Il est clair que le code permet de détecter au plus d-1 erreurs. Effectivement, sinon comment détecter un code erroné d'un code juste (code = message codé) ? Mis à part le fait que chaque élément du code soit différent (application injective de l'ensemble des messages à l'ensemble des message codés) il faut en plus pouvoir différencier parmi ceux-ci, ceux qui sont des codes erronés de ceux qui ne le sont pas. D'où le d-1.

CODES EN BLOCS - LINÉAIRES

Définition: Un "code en bloc" de taille equation défini sur un alphabet de q symboles (1 et 0 pour le langage binaire par exemple) est un ensemble de M vecteurs appelés "mots du code". Les vecteurs sont de longueur equation et leurs composantes sont q-aires (bin-aire pour le langage du même nom donc...)

Ainsi, selon la définition ci-dessus, un code en bloc C est une application bijective qui associe à chaque vecteur formé de k symboles q-aires (k symboles d'information), un vecteur image de longueur n avec des composantes dans le même alphabet (n symboles codés). Le code ajoute au débit initial n-k symboles supplémentaires. La quantité :

equation   (Eq.27)

est appelé le "rendement de C", ou encore "taux de codage". L'opération de codage en blocs est "sans mémoire", in extenso les blocs sont codés de manière indépendant sans aucune corrélation entre deux blocs consécutifs.

Maintenant il convient de revenir un peu sur les algèbres de Boole (cf. chapitre de Systèmes Logiques). Aux cinq axiomes qui définissent une algèbre de Boole ajoutons en un sixième qui lui confère une structure de corps :

A6. L'algèbre de Boole (extension d'un anneau unitaire par un axiome) muni de la loi * (equation) est un groupe.

Rappel (théorie des ensembles) : un corps est un anneau non nul dans lequel tout élément non nul est inversible.

Si nous prenons l'algèbre de Boole formée des equation éléments {0,1} formant un ensemble binaire, nous avons effectivement 1 qui est inversible puisqu'il existe x tel que equation qui est 1 lui-même.

Ce corps est noté equation. Dans les codes correcteurs, nous travaillons souvent dans equation (unique corps à deux éléments) où pour rappel l'addition est définie par :

0+0=0, 1+1=0 (donc 1=-1), 1+0=1   (Eq.28)

La multiplication étant définie par:

equation   (Eq.29)

Pour en revenir à notre théorie des codes : l'ensembles des messages equation peut être muni d'une structure d'espace vectoriel de dimension k sur equation (cf. chapitre de Théorie Des Ensembles). Effectivement, il suffisait pour cela que (E,+) soit un groupe abélien et * une loi externe définie par equation. Si nous décidons de n'utiliser que des encodeurs qui sont (des applications) linéaires, le code equation devient un sous-espace vectoriel de equation (car même si l'application est bijective, comme les corps des messages est fini, nous avons nécessairement un sous-espace vectoriel de l'espace vectoriel de tous les messages codés possibles).

Définition: Un "code linéaire" de dimension k et de "longueur" n est un sous-espace vectoriel de dimension k de equation (c'est ainsi que cela se dit...). Si la distance minimale de C est d, nous disons que C est une "code [n, k, d]" ou simplement "code [n,k]".

Remarque: Les codes linéaires sont donc un cas particulier des codes en blocs comme le montre le schéma hiérarchique au début de ce chapitre.

L'ajout de la contrainte de linéarité pourrait nuire à la qualité du code recherché, mais heureusement l'étude des performances montre que les codes linéaires sont très proches des meilleurs codes en blocs. Ainsi, la linéarité facilite l'étude des codes en blocs et permet l'utilisation des outils algébriques très puissants, sans réduire la classe des blocs linéaires à une classe inefficace.

Notons G la matrice de l'application linéaire equation. G est du type equation et tout mot c de C s'obtient à partir de tout mot x de E par equationequation et equation sont des vecteurs lignes avec toujours equation. Ainsi, equation.

Remarque: Les bases de equation sont les bases canoniques courantes (celles dont nous avons souvent fais usage dans le chapitre de calcul vectoriel).

Définition: soit C un code linéaire [n,k] et soit equation la base de C. Une "matrice génératrice" de C est donc une matrice equation dont les colonnes sont formées par les vecteurs equation de la base.

Soit equation le mot d'information, in extenso le vecteur contenant les k symboles d'information. Alors, nous pouvons écrire la relation matricielle liant le mot de code c et le mot d'information u :

equation   (Eq.30)

Définition: Soit C un code en blocs [n,k]. Ce code est dit "code systématique", si tous les mots de code contiennent les k symboles d'informations non modifiés. Les n-k symboles restant sont appelés "symboles de parité".

Remarque: Le "code de Hamming" est un tel code. Par ailleurs, les codes systématiques sont des cas particuliers des codes en blocs et nous reviendrons leur étude plus loin.

Définition: Soit H une matrice equation à éléments dans equation, qui vérifie equation pour tout mot c d'un code linéaire C (en d'autres termes : dont le noyau est C). Alors, H est dite "matrice de contrôle" du code C. Réciproquement, c appartient au Code si et seulement si equation. Sinon quoi il y a une erreur !

Remarque: Il est facile de trouver H car celle-ci est "orthogonale" à G puisque la définition ci-dessus implique equation donc equation (évidemment il ne faut pas prendre H=0...).

Voyons un exemple de tout cela avec le code de Hamming qui est un code en blocs systématique (attention !! il existerait plusieurs définition d'un "code de Hamming!) :

Cette méthode consiste à doubler l'information, en envoyant autant de bits de parité que de bits de données. Ainsi, à l'aide de matrices, il est possible de détecter et corriger les erreurs qui figurent dans les quartets. Une première matrice est  :

equation   (Eq.31)

Celle-ci est la matrice de codage G. Elle est de dimension equation, où n est le nombre de bits reçus par paquet, et k le nombre de bits par paquets contenant l'information (ici equation et equation). Elle permet de générer automatiquement les bits de parité propres à un message. Par exemple pour envoyer le message 1101, il faut, pour respecter la règle de multiplication des matrices, considérer ce quartet comme un vecteur colonne :

equation   (Eq.32)

Donc en multipliant nous obtenons :

equation   (Eq.33)

Nous enverrons donc l'octet 11010110, dont les quatre premiers bits forment le message et les quatre derniers les bits de parité, qui servent à vérifier la véracité/intégrité du message.

La matrice de contrôle correspondante H est :

equation   (Eq.34)

Ainsi lorsque le destinataire reçoit l'octet 11000110 au lieu de 11010110, le décodage donne comme "syndrome" :

equation   (Eq.35)

Le vecteur colonne obtenu n'est donc pas nul. Il y a donc une erreur. Avec la matrice de contrôle, la théorie permet d'affirmer que comme le vecteur obtenu est le même que celui en quatrième position dans la matrice de décodage, l'erreur est due au quatrième bit. Comme nous sommes en base 2, il suffit de changer le 0 en 1. Ce codage de l'information est coûteux car il occupe deux fois plus de bande passante. Cependant c'est l'un des moyens les plus efficaces pour sécuriser l'information.

Pour montrer que le syndrôme d'un code de Hamming correspond à une des colonnes de la matrice de contrôle, notons equation les vecteurs colonne de la base canonique sur equation, equation avec 1 à la i-ème place. Soit x un mot de code. Nous avons donc par définition de H, equation. Supposons que le mot reçu, que nous noterons equation, soit entaché d'une seule erreur et que cette erreur soit sur le j-ème bit. Nous avons donc :

equation et equation   (Eq.36)

ainsi il vient que equation, mais equation est le j-ème vecteur colonne de la matrice H.

Ceci nous montre bien que lorsque nous recevons equation et que nous calculons equation nous obtenons le vecteur colonne de la matrice H situé exactement à l'emplacement de l'erreur (en l'occurrence j).

Remarque: Un syndrome nul ne signifie pas l'absence d'erreur(s). Il existe donc des configurations d'erreurs indétectables.

Notons maintenant :

equation et equation   (Eq.37)

alors nous remarquerons que G et H sont formées par les blocs I et A de la manière suivante equation et equation. Ainsi :

equation   (Eq.38)

car 1+1=0 dans equation.

De façon générale, si nous travaillons avec l'alphabet equation et si equationA est une matrice equation alors equation est aussi une matrice de contrôle car de nouveau :

equation   (Eq.39)

Remarque: Dans equation, equation car 1=-1, c'est pour ça que nous avions écrit equation dans l'exemple précédant.

CODES SYSTÉMATIQUES

Un code systématique consiste à adjoindre à chaque mot equation du message n-k symboles equation dépendent linéairement des equation pour obtenir le mode de code equation.

Les symboles sont appelées "bits de contrôle" et (nous verrons un exemple juste plus bas) :

equation   (Eq.40)

equation désigne la matrice equation obtenue en écrivant l'une en-dessous de l'autre, la matrice identité equation de taille k et une matrice quelconque A. Nous dirons qu'un code C est systématique s'il possède une matrice génératrice de la forme equation

exempleExemple:

Nous nous proposons de construire un code linéaire systématique avec n=k=3. Nous notons equation les bits d'information. Les bits de contrôle equation seront définis par :

equation   (Eq.41)

La matrice génératrice G est telle que sa partie supérieure est la matrice identité de dimension 3 (nous avions la même chose pour le code de Hamming). La première ligne (110) de la matrice A correspond à l'expression du bit de contrôle equation :

equation   (Eq.42)

etc... pour chaque bit de contrôle.

La matrice génératrice G s'écrit alors :

equation   (Eq.43)

En multipliant cette matrice par les equation vecteurs possibles (les mots constitués de trois bits d'information), nous obtenons les mots code :

a1

a2

a3

a4

a5

a6

0

0

0

0

0

0

0

0

1

0

1

1

0

1

0

1

1

0

0

1

1

1

0

1

1

0

0

1

0

1

1

0

1

1

1

0

1

1

0

0

1

1

1

1

1

0

0

0

Tableau: 1  - Exemples de mots code

Nous constatons donc que le poids minimum des mots code est 3. Donc le code détecte 3-1=2 d'erreurs et peut en corriger equation.