home *** CD-ROM | disk | FTP | other *** search
- /*
- codage et decodage permettant de détecter 3 erreurs et d'en corriger 2
- Le facteur de multiplication du code a coder est de 3.
- Ce Source donne des exemples comment faire des decalages.
- Des Masques avec des and '&',et offre des fonctions interresantes:
-
- char get_bit(o,n)
- void put_bit(o,n,b)
- void inverse_bit(o,n)
- void aff_char -> en binaire
-
- Comment ca marche:
- Algo: on prend un octect , on le separe en deux :
- octect:x1x2x3x4x5x6x7x8 octect1:x1x2x3x4 octect2:x5x6x7x8
- on code par hamming octect1 et octect2 et on fait la somme bit a bit
- par octect3 ( octect de parité);
- c'est une operation xor : xor correspond a l'addition en base 2.
- on insert des erreurs ( <=3 erreurs ) dans les octects que l'on veut
- modifier.
- resultat:par hamming , on sait que l'on peut corriger 1 erreur et en
- detecte 2.
- donc si 1 erreur vient des 2 premier octects: erreur octect1
- erreur octect2
- par hamming on corrige.
- si 2 erreur vient dans un octect: on corrige grace a l'octect non
- affecté et par l'octect de parite.
- Pour 3 erreur , on regarde l'octect de parite , 3 different avec les
- autres, et voila;
- Ce n'est pas un code de detection , et de correction extraordinaire.
- Il faut savoir que hamming (dectecte 1 erreur sur 7 octect) est utilisé
- par le minitel.
- Sinon le code de detection d'erreur CRC, est equivalant a hamming.
- MAis il y a de code plus performant comme celui de Reed-Muller.
- auteur email:vidal@amertume.ufr-info-p7.ibp.fr
- */
- #include <stdio.h>
- typedef struct { int nb_error;
- char error[2];
- } ERREUR;
-
- /* affiche un char en binaire */
- void aff_char(o)
- char o;
- {
- char i;
- for (i=0;i<8;i++)
- if ((o>>i)&1) printf("1"); else printf("0");
- }
- /* renvoie le n^eme bit de o */
- char get_bit(o,n)
- char o,n;
- {return ((o>>n)&1);}
-
- /* met le n^eme bit de o a b */
- void put_bit(o,n,b)
- char *o;
- char n,b;
- {if (b) {b=b<<n;*o=*o|b;}
- else {b=1<<n;
- b^=255;*o=*o&b;}
- }
-
- void inverse_bit(o,n)
- char *o;
- char n;
- {
- put_bit(o,n,(get_bit(*o,n)^1));
- }
-
- /* codage hamming : code o -> code_hamming */
- char code_hamming(o)
- char o;
- {char i=0,a=0;
- o=o<<3;
- put_bit(&o,2,get_bit(o,3));
- put_bit(&o,0,(get_bit(o,2)^get_bit(o,4)^get_bit(o,6)));
- put_bit(&o,1,(get_bit(o,2)^get_bit(o,5)^get_bit(o,6)));
- put_bit(&o,3,(get_bit(o,4)^get_bit(o,5)^get_bit(o,6)));
- for (i=0;i<7;i++)
- a^=get_bit(o,i);
- put_bit(&o,7,a);
- return(o);
- }
- /* decodage hamming : decode o (o etant codé) -> decode_hamming */
- char decode_hamming(o)
- char *o;
- {
- char i=0,b,p=0;
- put_bit(&i,2,(get_bit(*o,3)^get_bit(*o,4)^get_bit(*o,5)^get_bit(*o,6)));
- put_bit(&i,1,(get_bit(*o,1)^get_bit(*o,2)^get_bit(*o,5)^get_bit(*o,6)));
- put_bit(&i,0,(get_bit(*o,0)^get_bit(*o,2)^get_bit(*o,4)^get_bit(*o,6)));
- p=get_bit(*o,7);
- if (!i) {put_bit(o,3,get_bit(*o,2));
- *o=*o>>3;
- *o=*o&0x0f;
- for (b=0;b<8;b++) p^=get_bit(*o,b);
- put_bit(&i,7,p);
- }
- else {for (b=0;b<8;b++) p^=get_bit(*o,b);
- put_bit(&i,7,p);}
- return (i);
- }
-
- void correction_hamming(o,i)
- char *o;
- char i;
- {
- inverse_bit(o,(i-1));
- }
-
- char somme_bit(e)
- char e;
- {char p=0,b;
- for (b=0;b<8;b++) p^=get_bit(e,b);
- return (p);
- }
-
- char nombre_erreur(e,a)
- char e;
- char *a;
- {
- *a=decode_hamming(&e);
- *a&=127;
- if (!*a) {
- return(0);
- }
- else {if (!somme_bit(e)) return(2);
- else return(1);
- }
- }
- /* decoupe un char en deux char */
- void decoupe1en2(o,t)
- char o;
- char *t;
- { t[0]=o;
- t[0]&=15;
- t[1]=o>>4;
- t[1]&=15;
- }
- /* inverse de decoupe1en2 */
- void regroupe2en1(t,o)
- char *t;
- char *o;
- { *o=t[0];
- t[1]<<=4;
- *o|=t[1];
- }
-
- char xor_bit_a_bit(a,b)
- char a,b;
- {
- char tempo;
- char i;
- for (i=0;i<8;i++)
- put_bit(&tempo,i,get_bit(a,i)^get_bit(b,i));
- return (tempo);
- }
-
- char nombre_xor_dif(t)
- char *t;
- {char tempo=0,i;
- for (i=0;i<8;i++)
- tempo+=get_bit(t[0],i)^get_bit(t[1],i)^get_bit(t[2],i);
- printf(" nombre xor dif %d\n",tempo);
- return (tempo);
- }
- /* compte le nombre d'erreur */
- char compte_erreur(t,erreur)
- char *t;
- ERREUR *erreur;
- {char xor_dif;
- erreur->nb_error=0;
- erreur->error[0]=0;
- erreur->error[1]=0;
- erreur->nb_error+=nombre_erreur(t[0],erreur->error);
- erreur->nb_error+=nombre_erreur(t[1],erreur->error+1);
- printf(" nombre erreur pour 2 char %d\n",erreur->nb_error);
- printf(" erreur 1 char %d\n",erreur->error[0]);
- printf(" erreur 2 char %d\n",erreur->error[1]);
- xor_dif=nombre_xor_dif(t);
- if (xor_dif>=3) {erreur->nb_error=3;return(3);}
- if (xor_dif==1 && erreur->nb_error==2) {erreur->nb_error=3;return(3);}
- if (xor_dif<=erreur->nb_error) {printf("pas d'erreur dans octect de parite \n");return(erreur->nb_error);}
- if (xor_dif<=2 && erreur->nb_error==0) return(0);
- if (xor_dif==2 && erreur->nb_error==1) return(1);
- if (xor_dif>erreur->nb_error) erreur->nb_error=3;
- return(erreur->nb_error);
- }
- /* corrige 0 1 2 erreurs */
- void correction_2erreurs(t,erreur)
- char *t;
- ERREUR erreur;
- {char e,i;
- switch (erreur.nb_error)
- { case 0:break;
- case 1: for (i=0;i<2;i++)
- {
- if (erreur.error[i]) {printf(" erreur dans %d ere char a %d \n",i,erreur.error[i]);correction_hamming(&t[i],erreur.error[i]);
- break;}
- }
- break;
- case 2:if (erreur.error[0] && erreur.error[1] && erreur.nb_error==2)
- { for (i=0;i<2;i++)
- {
- if (erreur.error[i]) {printf(" erreur dans %d ere char a %d \n",i,erreur.error[i]);correction_hamming(&t[i],erreur.error[i]);}
- }
- }
- else { if ((erreur.error[0] || erreur.error[1]) && (!erreur.error[0] || !erreur.error[1]) && erreur.nb_error==2)
- {printf(" le paquet d'erreur est regrouper dans un seul octet \n");
- if (erreur.error[0]) t[0]=xor_bit_a_bit(t[1],t[2]);
- else t[1]=xor_bit_a_bit(t[0],t[2]);
- }
- }
- break;
- default:break;
- }
- printf("decodagec");aff_char(t[0]);printf(" ");aff_char(t[1]);printf(" ");aff_char(t[2]);printf("\n");
- }
- void decodage_2char(t)
- char *t;
- {
- decode_hamming(t);t++;decode_hamming(t);
- }
- main ()
- {
- unsigned char i,o,whereerreur[10],quelbit[10],nb_inversion,cas,b;
- char t[3];
- ERREUR erreur;
- int in;
- printf(" entrez un nombre 0 255 ");
- scanf("%d",&in);
- i=(char ) in;
- printf(" nombre d'erreur 0 3 ");
- scanf("%d",&in);
- nb_inversion=(char) in;
- for (b=0;b<nb_inversion;b++)
- {
- printf(" entrez position erreur 0 2 ");
- scanf("%d",&in);
- whereerreur[b]=(char) in;
- printf(" entrez position bit erreur 0 7 ");
- scanf("%d",&in);
- quelbit[b]=(char) in;
- }
- decoupe1en2(i,t);
- printf("decoupage ");aff_char(i);printf(" ");aff_char(t[0]);printf(" ");aff_char(t[1]);printf("\n");
- t[0]=code_hamming(t[0]);
- t[1]=code_hamming(t[1]);
- t[2]=xor_bit_a_bit(t[0],t[1]);
- printf(" codage ");aff_char(t[0]);printf(" ");aff_char(t[1]);printf(" ");aff_char(t[2]);printf("\n");
- for (b=0;b<nb_inversion;b++)
- inverse_bit(&(t[whereerreur[b]]),quelbit[b]);
- printf(" erreur ");aff_char(t[0]);printf(" ");aff_char(t[1]);printf(" ");aff_char(t[2]);printf("\n");
- if (compte_erreur(t,&erreur)<3)
- {
- printf(" nb erreur %d \n",erreur.nb_error);
- correction_2erreurs(t,erreur);
- decodage_2char(t);
- printf("decodage ");aff_char(t[0]);printf(" ");aff_char(t[1]);printf(" ");aff_char(t[2]);printf("\n");
- printf(" regroupement ");regroupe2en1(t,&o);aff_char(o);printf("\n nombre %d\n",o);
- if (o!=i) fprintf(stderr," erreur programmation \n");
- }
- else printf(" nb erreur %d \n",erreur.nb_error);
- }
-