Как создать хеш md5 строки в C?
Я нашел некоторый код md5, который состоит из следующих прототипов...
Я пытаюсь выяснить, где мне нужно поставить строку, которую я хочу использовать, какие функции мне нужно вызвать, и где найти строку после ее хэширования. Я запутался в отношении того, что в структуре находятся uint32 buf [4] и uint32 bits [2].
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]);
Ответы
Ответ 1
Я не знаю эту конкретную библиотеку, но я использовал очень похожие вызовы. Так что это мое лучшее предположение:
unsigned char digest[16];
const char* string = "Hello World";
struct MD5Context context;
MD5Init(&context);
MD5Update(&context, string, strlen(string));
MD5Final(digest, &context);
Это вернет вам целочисленное представление хэша. Затем вы можете превратить это в шестнадцатеричное представление, если хотите передать его в виде строки.
char md5string[33];
for(int i = 0; i < 16; ++i)
sprintf(&md5string[i*2], "%02x", (unsigned int)digest[i]);
Ответ 2
Вот полный пример:
#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;
}
Ответ 3
Как упоминалось в других ответах, следующие вызовы будут вычислять хэш:
MD5Context md5;
MD5Init(&md5);
MD5Update(&md5, data, datalen);
MD5Final(digest, &md5);
Цель разделения на многие функции состоит в том, чтобы вы могли передавать большие наборы данных.
Например, если вы хешируете 10-гигабайтный файл и не вписываетесь в баран, вот как вы это сделаете. Вы будете читать файл в меньших фрагментах и называть MD5Update
на них.
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);
Ответ 4
Честно говоря, комментарии, сопровождающие прототипы, кажутся достаточно ясными. Что-то вроде этого должно сделать трюк:
void compute_md5(char *str, unsigned char digest[16]) {
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, str, strlen(str));
MD5Final(digest, &ctx);
}
где str
- строка C, в которой вы хотите хэш, а digest
- итоговый дайджест MD5.
Ответ 5
Казалось бы, вы должны
- Создайте
struct MD5context
и передайте его MD5Init
, чтобы получить его в правильное начальное условие
- Вызов
MD5Update
с контекстом и вашими данными
- Вызвать
MD5Final
, чтобы получить полученный хэш
Эти три функции и определение структуры делают хороший абстрактный интерфейс хэш-алгоритмом. Я не уверен, почему вам показали функцию преобразования ядра в этом заголовке, поскольку вам, вероятно, не следует напрямую взаимодействовать с ней.
Автор мог бы сделать немного больше скрытия реализации, создав структуру абстрактного типа, но тогда вам пришлось бы каждый раз выделять структуру в куче (в отличие от того, где вы можете положить ее в стек если вы этого желаете).