【问题标题】:What does this C code snippet mean?这个 C 代码片段是什么意思?
【发布时间】:2014-11-04 02:57:33
【问题描述】:

我遇到过这段代码here

result = HMAC(EVP_md5(), key, 32, data, 28, NULL, NULL);
  for (i = 0; i < result_len; i++) {
    sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
  }

循环有什么作用?特别是&amp;(res_hexstring[i * 2]) 是什么意思?您不能将结果作为数组进行迭代吗?为什么是整数?

【问题讨论】:

  • 作为十六进制字符串字符的八位字节表示为00FF。您可以一次只吃一点点,但这样做有什么意义,相当更多的工作没有收获?您可以假设 res_hexstring 除了转储到控制台之外的其他地方使用,否则是的,sprintf 毫无意义,可以使用 printf 完成。
  • 为什么不能只使用 printf?

标签: c hash


【解决方案1】:

它将哈希结果转换为字符串:

例如,来自:

char result[2] = {0xa1, 0xb2};

char res_hexstring[4 + 1] = {'a', '1', 'b', '2', '\0'}

表达式i * 2 出现在&amp;res_hexstring[i * 2] 中,因为字节0xa1 需要两个字符('a''1')才能在字符串中表示。

有一个字符串的好处是它可以很容易地显示出来:

printf("%s\n", res_hexstring);  // display the hash result

【讨论】:

    【解决方案2】:
    for (i = 0; i < result_len; i++) {
        sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
    }
    

    sprintf 将二进制数组 result 1 字节 2 个半字节/十六进制数字一次打印到缓冲区 res_hexstring 中。

    这就是第二个移动每 1 个字节左索引变为 2 个字节的原因。

    当然,不使用sprintf 会快得多,但也需要更多代码。
    (这可能会导致更大或更小的二进制文件,但如果感兴趣,必须对其进行测量。)

    inline char to16digit(int x) { return x<10 ? '0'+x : 'A'-10+x; }
    for (i = 0; i < result_len; i++) {
        res_hexstring[i*2]   = to16digit(result[i]>>4);
        res_hexstring[i*2+1] = to16digit(result[i]&15);
    }
    res_hexstring[2*result_len] = 0;
    

    出于各种原因,您可能希望它采用人类可读的形式,其中序列化、打印和日志记录尤为突出。 (而且printf 没有格式可以以十六进制表示法打印如此大的数字。)

    【讨论】:

    • 那么'result'的形式是什么?它被定义为 unsigned char* 结果;它是一个字符还是十六进制值的数组?哈希函数返回什么?
    • @w774: result 是一个长度为 result_len 的二进制 blob。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    相关资源
    最近更新 更多