Bonsoir à tous,

Depuis quelques jours, j'essaye de coder une fonction pour obtenir le MD5 d'une petit chaine de caractére ; je me suis basé sur le pseudo code disponible sur wikipédia : http://fr.wikipedia.org/wiki/Md5.

En Balise quote le pseudo-code et en balise code ce que j'ai "codé"

Selon le pseudo code, toute les variables sont sur 32 bits et sur mon systéme sizeof (int) = 4

Tout d'abord voici les 4 fonctions principales :






Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
int func_f (int b, int c, int d)
	{
	return ((b & c)|((~b) & d));
	}
 
int func_g (int b, int c, int d)
	{
	return ((b & d)|(c & (~d)));
	}
int func_h (int b, int c, int d)
	{
	return b^c^d;
	}
int func_i (int b, int c, int d)
	{
	return c ^ (b | (~d));
	}
var entier[64] r, k
r[ 0..15] := {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22}
r[16..31] := {5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20}
r[32..47] := {4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23}
r[48..63] := {6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}

//MD5 utilise des sinus d'entiers pour ses constantes:
pour i de 0 à 63 faire
k[i] := floor(abs(sin(i + 1)) × 2^32)
fin pour
Pour le tableau k, j'ai "fixé" les valeurs.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
unsigned int r[64] = {7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,
4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,
 6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21};
 
unsigned int k[64] = { 
74957514, 149892196, 224781220, 299601773, 374331064, 448946331, 523424844, 597743917,		//0-7
671880911,745813244, 819518394, 892973912, 966157421, 1039046629, 1111629334, 1183853428,	//8-15
1255726910, 1327217884, 1398304576, 1468965330, 1539178623, 1608923067, 1678177418, 1746920580,	//16-23
1815131612, 1882789738, 1949874349, 2016365008, 2082241463, 2147483648, 2212071687, 2275985909,	//24-31
2339206843, 2401715232, 2463492035, 2524518435, 2584775842, 2644245901, 2702910498, 2760751761,	//32-39
2817752073, 2873894071, 2929160652, 2983534983, 3037000499, 3089540917, 3141140230, 3191782721,	//40-47
3241452965, 3290135830, 3337816488, 3384480415, 3430113397, 3474701532, 3518231240, 3560689261,	//48-55
3602062661, 3642338838, 3681505523, 3719550786, 3756463038, 3792231035, 3826843881, 3860291034};//56-63
var entier h0 := 0x67452301
var entier h1 := 0xEFCDAB89
var entier h2 := 0x98BADCFE
var entier h3 := 0x10325476
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
unsigned int h[4] = {0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476};
ajouter "1" bit au message
ajouter "0" bits jusqu'à ce que la taille du message en bits soit égale à 448 (mod 512)
ajouter la taille du message codée en 64-bit little-endian au message
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
unsigned long long message_size = strlen(message);
unsigned long long nbr_paquet = (message_size/56)+1;
malloced_data = calloc(1,((56*nbr_paquet)+sizeof(long long int)));
memcpy(malloced_data,message,message_size);
memcpy(malloced_data+message_size,&add_1,1);
memcpy(malloced_data+56*nbr_paquet,&message_size,sizeof(long long int));
pour chaque bloc de 512 bits du message
subdiviser en 16 mots de 32 bits en little-endian w[i], 0 ≤ i ≤ 15
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
for (j = 0 ; j < nbr_paquet ; j++){
 for (i = 0 ; i < 16 ; i++){
  memcpy(&w[i],(malloced_data+(j*512))+(i*4),4);}
 //reste du code de la boucle principale
pour i de 0 à 63 faire
si 0 ≤ i ≤ 15 alors
f := (b et c) ou ((non b) et d)
g := i
sinon si 16 ≤ i ≤ 31 alors
f := (d et b) ou ((non d) et c)
g := (5×i + 1) mod 16
sinon si 32 ≤ i ≤ 47 alors
f := b xor c xor d
g := (3×i + 5) mod 16
sinon si 48 ≤ i ≤ 63 alors
f := c xor (b ou (non d))
g := (7×i) mod 16
fin si
fin si
fin si
fin si

var entier temp := d
d := c
c := b
b := ((a + f + k[i] + w[g]) leftrotate r[i]) + b
a := temp
fin pour
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
for (i = 0 ; i < 64 ; i++){
 if ( (i>= 0) | ( i<=15)){
  f = func_f(b, c, d);
  g = i;}
 else if ((i>= 16) | ( i<=31)){
  f = func_g (b, c, d);
  g = (5*i + 1)%16;}
 else if ((i>= 32) | ( i<=47)){
  f = func_h(b, c, d);
  g = (3*i + 5)%16;}
 else{
  f = func_i(b, c, d);
  g = (7*i)%16;}
 
temp = d;
d = c;
c = b;
b = ROTATE_LEFT (a + f + k[i] + w[g], r[i]) + b; 
a = temp;}
//ajouter le résultat au bloc précédent:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
h[0] += a;
h[1] += b;
h[2] += c;
h[3] += d;
Voici le code complet : http://pastebin.com/fjL3GJMK

Le souci, est que le hash est faux et en plus si on exécute le programme 2 fois sur le même mot le hash diffère à chaque fois.

Auriez vous une idée, est ce un souci d'algo ou de "codage" ?

Merci d'avance.

Bonne soirée

EDIT : J'ai vu plusieurs de mes erreurs, ca m'apprendra à ne pas faire de break ...

Je corrige ca dans les jours à venir