我发现了一些由以下原型组成的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]);
答案 0 :(得分:38)
我不知道这个特定的库,但我使用了非常类似的调用。所以这是我最好的猜测:
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]);
答案 1 :(得分:33)
这是一个完整的例子:
#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;
}
答案 2 :(得分:7)
正如其他答案所提到的,以下调用将计算哈希值:
MD5Context md5;
MD5Init(&md5);
MD5Update(&md5, data, datalen);
MD5Final(digest, &md5);
将其拆分为多个函数的目的是让您流式传输大型数据集。
例如,如果您正在对10GB文件进行哈希处理并且它不适合ram,那么您可以采用以下方式进行操作。您可以用较小的块读取文件并在其上调用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);
答案 3 :(得分:5)
老实说,原型附带的评论似乎很清楚。这样的事情可以解决问题:
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摘要。
答案 4 :(得分:1)
看起来你应该
struct MD5context
并将其传递给MD5Init
以使其进入正常的起始条件MD5Update
MD5Final
以获取生成的哈希值这三个函数和结构定义为哈希算法提供了一个很好的抽象接口。我不确定为什么你会在那个标题中显示核心转换函数,因为你可能不应该直接与它进行交互。
作者可以通过使结构成为抽象类型来进行更多的实现隐藏,但是每次都会被迫在堆上分配结构(而不是现在可以将它放在堆栈上)如果你愿意的话。)
答案 5 :(得分:0)
所有现有答案都使用deprecated MD5Init()
,MD5Update()
和MD5Final()
。
例如,使用EVP_DigestInit_ex()
,EVP_DigestUpdate()
和EVP_DigestFinal_ex()
,例如
// example.c
//
// gcc example.c -lssl -lcrypto -o example
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
void bytes2md5(const char *data, int len, char *md5buf) {
// Based on https://www.openssl.org/docs/manmaster/man3/EVP_DigestUpdate.html
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
const EVP_MD *md = EVP_md5();
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len, i;
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, data, len);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
for (i = 0; i < md_len; i++) {
snprintf(&(md5buf[i * 2]), 16 * 2, "%02x", md_value[i]);
}
}
int main(void) {
const char *hello = "hello";
char md5[33]; // 32 characters + null terminator
bytes2md5(hello, strlen(hello), md5);
printf("%s\n", md5);
}