如何将MD5生成的十六进制值存储为整数?

发布于 2025-01-06 22:53:28 字数 879 浏览 1 评论 0原文

我使用以下代码生成字符串的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海少女心 2025-01-13 22:53:28

您正在打印每个字节的十进制值(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 your value 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",...)).

℡寂寞咖啡 2025-01-13 22:53:28

您无法在 int 中存储 128 位值(除非 int 在您的 C 实现上至少为 128 位,但我确信它不是)。最大的标准整数类型long long也是如此。

您打印的十进制值是“254”(0xfe 的十进制),后跟“23”(0x17 的十进制),依此类推。它基本上没有意义——如果你像这样表示0x0100010x0A01,你会得到相同的字符串,101。您得到 36 位数字,因为这恰好是每个 16 字节值中的十进制数字总数。

您打印的十六进制值的长度为 32 个字符(每个字符 4 位,32 个字符,128 位)。这实际上有点运气,摘要中的每个字节恰好至少是 0x10。您应该使用 %02x 进行打印,以包含小值的前导 0。

如果您想将 128 位值表示为十进制字符串,那么您需要 bignum 库或长除法。但是用十进制表示 MD5 校验和是毫无意义的:当人们将它们表示为字符串时,他们总是使用十六进制。

如果有人能解释这些值如何存储在无符号字符中,那就太好了

在每个 unsigned char 中摘要的 unsigned char 8 位中,数组中的 16 个无符号字符构成 128 位,那就太好了。您不能使用 sscanfstrtol,因为 MD5Final 存储的值不是字符串。

You can't store a 128-bit value in an int (unless int is at least 128 bits on your C implementation, which I confidently predict it isn't). Same goes for long long, the biggest standard integer type.

The decimal value you've printed is "254" (decimal for 0xfe), followed by "23" (decimal for 0x17), and so on. It's basically meaningless -- if you represented either 0x010001 or 0x0A01 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.

It'll be nice of someone can explain how the values are being stored in the unsigned char

8 bits of the digest in each unsigned char, 16 unsigned chars in the array, makes 128 bits. You can't use sscanf or strtol because the value stored by MD5Final is not a string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文