如何将MD5生成的十六进制值存储为整数?
我使用以下代码生成字符串的 MD5 哈希值。以十六进制打印的值似乎是正确的(我在网站上验证了同一字符串)。但是,当我将值打印为整数时,它有 36 位数字。我的理解是它应该有 16 位数字,因为生成的哈希值是 128 位长。
我想知道如何从 unsigned char 到 int 的转换以及如何将其存储在变量中,以便最终可以将其打印到文件中。
如果有人能解释这些值如何存储在无符号字符中,例如需要多少位来表示十六进制和十进制的一位数字以及如何在它们之间进行转换,那就太好了。我尝试了 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
I am using the following code to generate the MD5 hash for a string. The value printed in hex seems to be correct (i verified it on a website for the same string). However when I print the value as an integer it has 36 digits. My understanding is that it should have 16 digits because the hash generated is 128 bits long.
I'm want to know how the conversion from the unsigned char to int should be done and how can this be stored in a variable, so that it can ultimately be printed to a file.
It'll be nice of someone can explain how the values are being stored in the unsigned char, like how many bits is it taking to represent one digit of the hex and decimal and how can i convert between them. I tried sscanf and strtol but i guess i am not using them right.
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");
}
THe output here is
fe17ec3c451f132ef82a3a54e84a461e
254232366069311946248425884232747030
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在打印每个字节的十进制值(254、23、236...),而不是转换为 int 的单个 128 位值。您的循环应类似于
value <<= 8; value+=output[i++]
(前提是您的value
是可以容纳这么大数字的类型)。您对结果应该有多少位的预期也与预期不符;除非打印前导零,否则其长度可以是 1 到 len(2**128-1) 之间的任何值,即 39 位十进制数字。
顺便说一句,您还应该对十六进制输出进行零填充,否则任何值低于 16 的字节都将打印单个十六进制数字 (
printf("%02x",...)
)。You are printing the decimal value of each byte (254, 23, 236, ...), not a single 128-bit value converted to an int. Your loop should look something like
value <<= 8; value+=output[i++]
(provided yourvalue
is a type which can accommodate such a big number).Your expectancy for how many digits the result should be is also off; unless you print leading zeros, its length could be anything between 1 and len(2**128-1), which is 39 decimal digits.
By the by, you should also zero-pad your hex output, otherwise any byte with a value below 16 will print a single hex digit (
printf("%02x",...)
).您无法在
int
中存储 128 位值(除非int
在您的 C 实现上至少为 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
存储的值不是字符串。You can't store a 128-bit value in an
int
(unlessint
is at least 128 bits on your C implementation, which I confidently predict it isn't). Same goes forlong long
, the biggest standard integer type.The decimal value you've printed is "254" (decimal for
0xfe
), followed by "23" (decimal for0x17
), and so on. It's basically meaningless -- if you represented either0x010001
or0x0A01
like this you'd get the same string,101
. You got 36 digits because that happens to be the total number of decimal digits in each of the 16 byte values.The hex value you've printed is 32 characters long (4 bits per character, 32 characters, 128 bits). This is actually a bit of luck, that each byte in your digest happens to be at least
0x10
. You should print with%02x
to include a lead 0 for small values.If you want to represent a 128-bit value as a decimal string then you need either a bignum library or else long division. But it's fairly pointless to express MD5 checksums in decimal: when people represent them as strings they always use hex.
8 bits of the digest in each
unsigned char
, 16 unsigned chars in the array, makes 128 bits. You can't usesscanf
orstrtol
because the value stored byMD5Final
is not a string.