Как создать md5 хэш строки в C? - PullRequest
34 голосов
/ 02 октября 2011

Я нашел некоторый код md5, который состоит из следующих прототипов ...

Я пытался выяснить, где я должен поместить строку, которую я хочу хэшировать, какие функции мне нужнывызов, и где найти строку после того, как она была хеширована.Меня смущает вопрос о том, что в структуре есть биты uint32 buf [4] и uint32 [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]);

Ответы [ 5 ]

38 голосов
/ 02 октября 2011

Я не знаю эту конкретную библиотеку, но я использовал очень похожие вызовы.Так что это мое лучшее предположение:

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]);
33 голосов
/ 05 декабря 2011

Вот полный пример:

#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;
    }
7 голосов
/ 02 октября 2011

Как уже упоминалось в других ответах, следующие вызовы будут вычислять хеш:

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);
5 голосов
/ 02 октября 2011

Если честно, комментарии, сопровождающие прототипы, кажутся достаточно ясными. Нечто подобное должно сработать:

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.

1 голос
/ 02 октября 2011

Похоже, что вы должны

  • Создайте struct MD5context и передайте его MD5Init, чтобы привести его в правильное начальное состояние
  • Звоните MD5Update с контекстом и вашими данными
  • Позвоните MD5Final, чтобы получить полученный хэш

Эти три функции и определение структуры создают красивый абстрактный интерфейс к алгоритму хеширования. Я не уверен, почему вам показали основную функцию преобразования в этом заголовке, поскольку вам, вероятно, не следует взаимодействовать с ней напрямую.

Автор мог бы сделать немного больше сокрытия реализации, сделав структуру абстрактным типом, но тогда вам пришлось бы каждый раз выделять структуру в куче (в отличие от того, где вы можете поместить ее в стек если ты так хочешь).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...