1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <string.h>
// Table de conversion pour l'encodage.
char B64LUT[64] ;
// Conversion d'un entier en chiffre hexa.
#define nibble2hex(n) ((char)(((n)<10) ? ('0'+(n)) : ('A'+((n)-10))))
// Préparation de la LUT de conversion.
// A n'appeler qu'une seule fois dans le programme !
void CreateLUT64 ( char* LUT ) {
int i ;
// Remplissage simple
for (i=0;i<10;i++)
// Codes numériques.
LUT[i]=(char)('0'+i);
for (i=10;i<36;i++)
// Codes alphabétiques : majuscules.
LUT[i]=(char)('A'+(i-10));
for (i=36;i<62;i++)
// Codes alphabétiques : minuscules.
LUT[i]=(char)('a'+(i-36));
// Codes alphabétiques : autres codes.
LUT[62]='#';
LUT[63]='-';
}
// Fonction d'encodage unitaire : 3 chars "hexa" -> 2 chars "compactés".
void Encode64 ( char* HexaString, char* B64String ) {
unsigned int value ;
char tmp[4] ;
// Recopie de la chaine hexa (3 caractères seulement).
strncpy(tmp,HexaString,3);
tmp[3]=0;
// Conversion hexa->numérique.
sscanf(tmp,"%x",&value);
// Encodage : découpage des 2 codes 6 bits et conversion.
*(B64String++)=B64LUT[((value>>6) & 0x3F)];
*B64String=B64LUT[value & 0x3F];
}
// Compactage d'une empreinte MD5. Les buffers doivent être corrects et alloués.
// Retourne la chaîne compactée.
char* PackMD5 ( char* MD5, char* Packed, int CollisionIndex ) {
char tmd5[34] ;
char* tmp = tmd5 ;
char* pck = Packed ;
// Copie et complétion du MD5.
memcpy(tmd5,MD5,32);
// Calcul du chiffre hexa correspondant au numéro de collision.
tmd5[32]=nibble2hex((CollisionIndex & 0x0F));
tmd5[33]=0;
// Encodage, par paquets de 3/2.
for ( int i=0 ; i<22 ; i+=2, tmp+=3, pck+=2 )
Encode64(tmp,pck);
// Ajout du zéro terminal.
Packed[22]=0;
return Packed;
}
void main ( void ) {
char md5[33] ;
char packed[23] ;
int i, j, v ;
// Initialisation des buffers (pour zéro terminal notamment).
memset(md5,0,sizeof(md5));
memset(packed,0,sizeof(packed));
// Création de la table d'encodage.
CreateLUT64(B64LUT);
// Initialisation générateur aléatoire.
srand(time(NULL));
// Conversions d'exemple : 10 conversions aléatoires.
for (j=0;j<10;j++) {
// Création d'un MD5 pour l'exemple.
for (i=0;i<32;i++) {
v = (rand() & 0x0F) ;
md5[i]=nibble2hex(v); // Attention, c'est une macro !!
}
printf("\nOriginal MD5 checksum : %s\n",md5);
for (i=0;i<16;i+=15) {
PackMD5(md5,packed,i);
printf("Packed checksum (coll. %02d) : %s\n",i,packed);
}
}
} |
Partager