Comment créer un hachage md5 d'une chaîne en C?
J'ai trouvé du code md5 composé des prototypes suivants...
J'ai essayé de savoir où je dois mettre la chaîne que je veux hacher, quelles fonctions je dois appeler, et où trouver la chaîne une fois qu'elle a été hachée. Je suis confus en ce qui concerne ce que les bits uint32 buf[4] et UInt32[2] sont dans la structure.
struct MD5Context {
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
};
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void MD5Init(struct MD5Context *context);
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len);
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void MD5Final(unsigned char digest[16], struct MD5Context *context);
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void MD5Transform(uint32 buf[4], uint32 const in[16]);
5 réponses
Je ne connais pas cette bibliothèque particulière, mais j'ai utilisé des appels très similaires. Donc, c'est ma meilleure estimation:
unsigned char digest[16];
const char* string = "Hello World";
struct MD5Context context;
MD5Init(&context);
MD5Update(&context, string, strlen(string));
MD5Final(digest, &context);
Cela vous donnera une représentation entière du hachage. Vous pouvez ensuite transformer cela en une représentation hexadécimale si vous voulez le passer sous forme de chaîne.
char md5string[33];
for(int i = 0; i < 16; ++i)
sprintf(&md5string[i*2], "%02x", (unsigned int)digest[i]);
Voici un exemple complet:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__APPLE__)
# define COMMON_DIGEST_FOR_OPENSSL
# include <CommonCrypto/CommonDigest.h>
# define SHA1 CC_SHA1
#else
# include <openssl/md5.h>
#endif
char *str2md5(const char *str, int length) {
int n;
MD5_CTX c;
unsigned char digest[16];
char *out = (char*)malloc(33);
MD5_Init(&c);
while (length > 0) {
if (length > 512) {
MD5_Update(&c, str, 512);
} else {
MD5_Update(&c, str, length);
}
length -= 512;
str += 512;
}
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
}
return out;
}
int main(int argc, char **argv) {
char *output = str2md5("hello", strlen("hello"));
printf("%s\n", output);
free(output);
return 0;
}
Comme d'autres réponses l'ont mentionné, les appels suivants calculeront le hachage:
MD5Context md5;
MD5Init(&md5);
MD5Update(&md5, data, datalen);
MD5Final(digest, &md5);
Le but de le diviser en autant de fonctions est de vous permettre de diffuser de grands ensembles de données.
Par exemple, si vous hachez un fichier de 10 Go et qu'il ne rentre pas dans la ram, voici comment vous le feriez. Vous liriez le fichier en petits morceaux et appelez MD5Update
sur eux.
MD5Context md5;
MD5Init(&md5);
fread(/* Read a block into data. */)
MD5Update(&md5, data, datalen);
fread(/* Read the next block into data. */)
MD5Update(&md5, data, datalen);
fread(/* Read the next block into data. */)
MD5Update(&md5, data, datalen);
...
// Now finish to get the final hash value.
MD5Final(digest, &md5);
, Pour être honnête, les commentaires accompagnant les prototypes semblent assez claires. Quelque chose comme ça devrait faire l'affaire:
void compute_md5(char *str, unsigned char digest[16]) {
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, str, strlen(str));
MD5Final(digest, &ctx);
}
Où str
est une chaîne C dont vous voulez le hachage, et digest
est le résumé MD5 résultant.
, Il semblerait que vous devriez
- Créez un
struct MD5context
et passez-le àMD5Init
pour l'obtenir dans une condition de départ appropriée - Appel de
MD5Update
avec le contexte et vos données - appelez
MD5Final
pour obtenir le hachage résultant
Ces trois fonctions et la définition de la structure font une belle interface abstraite à l'algorithme de hachage. Je ne sais pas pourquoi on vous a montré la fonction de transformation de base dans cet en-tête car vous ne devriez probablement pas interagir directement avec elle.
Le l'auteur aurait pu faire un peu plus de cache d'implémentation en faisant de la structure un type abstrait, mais alors vous auriez été obligé d'allouer la structure sur le tas à chaque fois (par opposition à maintenant où vous pouvez le mettre sur la pile si vous le désirez).