我使用以下代码为字符串生成MD5哈希。以十六进制打印的值似乎是正确的(我在网站上验证了相同的字符串)。但是,当我将值打印为整数时,它有36位数。我的理解是它应该有16位数,因为生成的哈希值是128位长。
我想知道如何将unsigned char转换为int以及如何将其存储在变量中,以便最终将其打印到文件中。
有人可以解释这些值是如何存储在unsigned char中的,这很好,比如表示十六进制和十进制的一位数以及如何在它们之间进行转换需要多少位。我尝试过sscanf和strtol,但我想我没有正确使用它们。
int main (void)
{
char *str = "tell";
u_int8_t *output; //unsigned char
output = malloc(16 * sizeof(char));
int i = 0;
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, str, strlen(str));
MD5Final(output, &ctx);
while(i < 16)
printf("%x",output[i++]);
printf("\n");
i = 0;
while(i < 16)
printf("%i",output[i++]);
printf("\n");
}
这里的输出是
fe17ec3c451f132ef82a3a54e84a461e
254232366069311946248425884232747030
答案 0 :(得分:3)
您不能在int
中存储128位值(除非{C}实现中int
至少为128位,我自信地预测它不是这样。同样适用于long long
,最大的标准整数类型。
您打印的十进制值为“254”(0xfe
的十进制数),后跟“23”(0x17
的十进制数),依此类推。它基本上没有意义 - 如果您像这样表示0x010001
或 0x0A01
,您将获得相同的字符串101
。你有36位数,因为它恰好是每个16字节值中的小数位总数。
您打印的十六进制值长度为32个字符(每个字符4位,32个字符,128位)。这实际上有点幸运,你的摘要中的每个字节恰好至少为0x10
。您应该使用%02x
进行打印,以包含小值的前导0。
如果要将128位值表示为十进制字符串,则需要bignum库或长除法。但用十进制表示MD5校验和是毫无意义的:当人们将它们表示为字符串时,他们总是使用十六进制。
有人可以解释如何将值存储在unsigned char
中
每个unsigned char
中的8位摘要,数组中的16个无符号字符,产生128位。您无法使用sscanf
或strtol
,因为MD5Final
存储的值不是字符串。
答案 1 :(得分:3)
您正在打印每个字节的十进制值(254,23,236,...),而不是一个转换为int的128位值。您的循环应该类似于value <<= 8; value+=output[i++]
(前提是您的value
是一种可以容纳如此大数字的类型。)
您对结果应该是多少位数的期望也是关闭的;除非你打印前导零,否则它的长度可以是1到len(2 ** 128-1)之间的任何值,即39位十进制数。
顺便说一句,你也应该对十六进制输出进行零填充,否则任何值低于16的字节都将打印一个十六进制数字(printf("%02x",...)
)。