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)); }Pour le tableau k, j'ai "fixé" les valeurs.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
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-63var 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 principalepour 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 + dVoici le code complet : http://pastebin.com/fjL3GJMK
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;
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
Partager