Les données ne sont pas assurées contre leur éventuelle modification lors du transport. Cela présente un risque du point de vue de l'intégrité des informations.
L'astuce de la méthode est de découper les données en blocs (de 4 bits) qui seront transformés en blocs de 8 bits. Le HammingIn fait donc 4 bits et le HammingOut 8 bits. Le HammingOut est constitué des 4 bits du HammingIn suivis de 4 bits de controle d'intégrité. Le transport a alors lieu, les données se modifient et on récupère un flux de paquets de 8 bits. A chaque captation, par une méthode en XOR, on extrait une empreinte caractéristique qui permet de retrouver le bit modifié dans le paquet. Il suffit alors de corriger le paquet, et on refait l'opération. Mais si la signature est vide, alors le paquet offre ses 4 premiers bits en guise de message et de proche en proche s'effectue un rappatriement de données avec correction du signal.
Bien que rudimentaire sur 4 bits, la méthode reste la même sur de plus gros bitages. Mais quoi qu'il en soit, c'est vraiment surprenant.
Pour d'autres explications, j'ai après cherché quelques liens, si cela peut intéresser. Des explications pour les goûts :
http://cermics.enpc.fr/polys/oap/node52.html
http://www.irisa.fr/armor/lesmembres/cousin/Enseignement/Reseaux-generalites/Cours/3-2.htm
http://mathworld.wolfram.com/HammingCode.html
http://www.ee.unb.ca/tervo/ee4253/hamming.htm
http://web.usna.navy.mil/~wdj/book/node123.html
http://www.mth.pdx.edu/~caughman/thesis.pdf#search='hamming code'
Source / Exemple :
program Hamming;
uses SysUtils;
(* ========================================================= *)
(* *)
(* Méthode de Hamming: transmission de données sans erreur *)
(* © Tanguy Altert, http://altert.family.free.fr/ *)
(* *)
(* Août 2005 *)
(* *)
(* ========================================================= *)
{$APPTYPE Console}
const BPower : array[0..7] of byte = (1, 2, 4, 8, 16, 32, 64, 128);
BinChar : packed array[boolean] of char = '01';
Separator = '=============================================';
type THData = string[8];
var Texte : string;
Orn : byte;
BinMem : string;
BinBuff : string;
BinDump : string;
BinHamg : string;
ModifCount : integer;
HammingIn : array[1..4] of boolean;
HammingOut : array[1..8] of boolean;
idx, pw : integer;
bool : boolean;
s : string;
WillRepair : boolean;
(***************************************************************************)
(* Cette partie simule un correspondant distant recevant les données. *)
(* Le corps principal du programme n'est pas censé pouvoir modifier *)
(* directement les variables suivantes (d'où l'utilisation de procédures *)
(* telles que SetRepair. Cela simule des conversations sur un réseau. *)
var PackCount, ErrorCount : integer;
HMsg : string;
DoRepair : boolean;
procedure RevTransf;
begin
HammingIn[1]:=HammingOut[1] xor HammingOut[2] xor HammingOut[5];
HammingIn[2]:=HammingOut[3] xor HammingOut[4] xor HammingOut[6];
HammingIn[3]:=HammingOut[1] xor HammingOut[3] xor HammingOut[7];
HammingIn[4]:=HammingOut[2] xor HammingOut[4] xor HammingOut[8];
end;
procedure SetRepair(State:boolean);
begin
DoRepair:=State;
end;
procedure Init;
begin
PackCount:=0;
ErrorCount:=0;
DoRepair:=false;
HMsg:='';
end;
procedure Send(Data:THData);
var Sgn : byte;
EBit : byte;
i : integer; //la variable de boucle doit être locale
label ReCheck;
begin
inc(PackCount);
//CONVERTISSONS LE SIGNAL REÇU EN TABLEAU DE BOOLÉENS
for i:=1 to 8 do
HammingOut[i]:= Data[i]='1';
ReCheck:
RevTransf;
//REPÉRONS LA SIGNATURE (EN BINAIRE INVERSÉ)
Sgn:=0;
for i:=1 to 4 do
Sgn:=Sgn+ Ord(HammingIn[i]) * BPower[i-1];
//CORRECTION DU SIGNAL [1, 2, 4, 8, 16, 32, 64, 128]
case Sgn of
0 {0000}: EBit:=0; //le signal est OK !
1 {1000}: EBit:=5;
2 {0100}: EBit:=6;
4 {0010}: EBit:=7;
5 {1010}: EBit:=1;
6 {0110}: EBit:=3;
8 {0001}: EBit:=8;
9 {1001}: EBit:=2;
10 {0101}: EBit:=4;
else EBit:=0; //pas de correction possible
end;
if EBit>0 then
begin
inc(ErrorCount);
WriteLn(' Erreur sur le bit N°',EBit,' du paquet N°',PackCount,' envoyé');
if DoRepair then
begin
HammingOut[EBit]:=not HammingOut[EBit]; //le HammingIn a juste servi comme détecteur d'erreur et pas comme le décompilé du HammingOut
goto ReCheck;
end;
end;
//MÉMORISATION DU PAQUET
for i:=1 to 4 do
HMsg:=HMsg+ BinChar[HammingOut[i]];
end;
procedure Final;
var i : integer;
begin
WriteLn('Le correspondant a reçu ',PackCount,' paquets, soit ',8*PackCount,' bits.');
case ErrorCount of
0: WriteLn('Aucune erreur n''a été détectée.');
1: WriteLn(ErrorCount,' erreur a été détectée.');
else WriteLn(ErrorCount,' erreurs ont été détectées.');
end;
WriteLn;
WriteLn('Le message binaire reçu est :');
WriteLn(HMsg);
WriteLn;
WriteLn('Il correspond au message original suivant :');
//ON DECODE LE DUMP BINAIRE
BinBuff:=HMsg;
Texte:='';
repeat
BinMem:=Copy(BinBuff,1,8);
Orn:=0;
for i:=1 to 8 do
Orn:=Orn + BPower[i-1]*StrToInt(BinMem[i]);
Texte:=Texte + Chr(Orn);
Delete(BinBuff,1,8);
until BinBuff='';
WriteLn(Texte);
end;
(* *)
(* *)
(* *)
(**************************************************************************)
label ReDo;
begin
//TITRE
WriteLn('Méthode de Hamming : transmission de données sans erreur');
WriteLn(Separator);
WriteLn;
//SAISIE DU TEXTE
ReDo:
SetRepair(false);
WriteLn('Saisissez le texte à transmettre virtuellement :');
ReadLn(Texte);
//DUMP BINAIRE
BinDump:='';
for idx:=1 to Length(Texte) do
begin
Orn:=Ord(Texte[idx]);
for pw:=0 to 7 do
BinDump:=BinDump + BinChar[Orn and BPower[pw]>0];
//ATTENTION: c'est un dump binaire inversé, c'est à dire que 2^0 se trouve à gauche et 2^7 à droite
end;
WriteLn;
WriteLn(Separator);
WriteLn('L''anti-dump binaire associé est :');
WriteLn(BinDump);
//TRAITEMENT DU SIGNAL
BinHamg:='';
BinBuff:=BinDump;
repeat
//on traite les données par 4 bits (c'est pourquoi on a dumpé en binaire)
BinMem:=Copy(BinBuff,1,4);
for idx:=1 to 4 do
HammingIn[idx]:= BinMem[idx]='1';
//transformation mathématique
HammingOut[1]:=HammingIn[1];
HammingOut[2]:=HammingIn[2];
HammingOut[3]:=HammingIn[3];
HammingOut[4]:=HammingIn[4];
HammingOut[5]:=HammingIn[1] xor HammingIn[2];
HammingOut[6]:=HammingIn[3] xor HammingIn[4];
HammingOut[7]:=HammingIn[1] xor HammingIn[3];
HammingOut[8]:=HammingIn[2] xor HammingIn[4];
//constitution du signal de sortie et effacement du premier paquet de 4 bits situé au début
for idx:=1 to 8 do
BinHamg:=BinHamg + BinChar[HammingOut[idx]];
Delete(BinBuff,1,4);
until BinBuff='';
WriteLn;
WriteLn('Le signal de Hamming associé est :');
WriteLn(BinHamg);
//Naturellement, le dump de Hamming est deux fois plus lourd que le dump binaire.
//Il reste quand même un avantage: il est possible de réparer le signal s'il y a
//des erreurs, ce que ne permet pas un simple dump binaire.
//POSSIBILITE DE MODIFIER LE DUMP
WillRepair:=false;
WriteLn;
WriteLn('Le but de ce code est de détecter les erreurs de transmission.');
WriteLn('Vous pouvez modifier quelques bits de Hamming, mais vous allez');
WriteLn('vous faire griller lors de la réception (sauf s''il y a');
WriteLn('compensation des erreurs)...');
WriteLn;
Write ('Voulez-vous modifier des bits ? (oui/non) ');
ReadLn(s);
if LowerCase(s)='oui' then
begin
WriteLn;
WriteLn('Tapez "-1" pour arrêter. Sachez qu''il y a ',Length(BinHamg),' bits dans le message...');
ModifCount:=0;
bool:=false;
repeat
Write(' Bit N°');
ReadLn(idx);
if (idx=-1) or (idx>Length(BinHamg)) then
bool:=true
else
begin
BinHamg[idx]:=BinChar[not boolean(StrToInt(BinHamg[idx]))];
inc(ModifCount);
end;
until bool;
WriteLn;
WriteLn(ModifCount,' bits du signal ont été modifiés...');
WriteLn;
WriteLn(Separator);
WriteLn('Le signal de Hamming est maintenant celui-ci :');
WriteLn(BinHamg);
if ModifCount>0 then
begin
WriteLn;
WriteLn('Vous avez la possibilité d''activer le correcteur d''erreur.');
Write ('Souhaitez-vous le faire ? (oui/non) ');
ReadLn(s);
WillRepair:= LowerCase(s)='oui';
end;
end;
//ENVOI DU MESSAGE
WriteLn;
WriteLn(Separator);
Init;
SetRepair(WillRepair);
BinBuff:=BinHamg;
repeat
Send(Copy(BinBuff,1,8));
Delete(BinBuff,1,8);
until BinBuff='';
//FINALISATION DU TRAITEMENT ET PURGE DE LA MEMOIRE
WriteLn;
WriteLn(Separator);
Final;
BinMem:='';
BinBuff:='';
BinDump:='';
BinHamg:='';
//POSSIBILITE DE RECOMMENCER
WriteLn;
WriteLn(Separator);
Write('Souhaitez-vous recommencer ce test très convaincant ? (oui/non) ');
ReadLn(s);
if LowerCase(s)='oui' then
begin
for idx:=1 to 5 do
WriteLn;
goto ReDo;
end;
end.
Conclusion :
Vous pouvez toujours aller visiter
http://altert.family.free.fr/
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.