gpt4 book ai didi

c - 如何将无符号字符数组解释为十六进制数组?

转载 作者:行者123 更新时间:2023-12-04 10:46:52 25 4
gpt4 key购买 nike

我有一个无符号字符数组,我想计算它的 CRC32 校验和。

CRC32 函数还需要一个无符号字符指针,但是,它将数组解释为 ASCII 数组。

这是 CRC 函数:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

unsigned int crc32(unsigned char *message)
{
int i, j;
unsigned int byte, crc, mask;

i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
byte = message[i]; // Get next byte.
crc = crc ^ byte;
for (j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}

int main(int argc, char **argv)
{
unsigned char *arr;
if ((arr = malloc(64)) == NULL) {
perror("Could not allocate memory");
exit(EXIT_FAILURE);
}
char str[] = "47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000";
memcpy(arr, str, strlen(str));
// ...
unsigned int crc = crc32(arr);
printf("CRC: 0x%x\n", crc); // 0xB6BA014A instead of 0xBF6B57A2

return 0;
}

现在,我想计算 CRC32,但必须将 unsigned char 数组解释为十六进制数组。

例如,这是计算出的 CRC 的结果:
输入:
“47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000”

  • 作为 ASCII:0xB6BA014A(这是我通常得到的,因为它被解释为 ASCII)
  • 十六进制:0xBF6B57A2(这是我想要的校验和)

最佳答案

How to interpret an unsigned char array as hex array?

  • 将字符串中的每对十六进制字符转换为字节值。下面的代码通过复合文字 转换为 3 字节的字符串,然后调用 strtoul()

    //                    v----------------------------------v _compound literal_
    arr2[i / 2] = strtoul((char[3]) {str[i], str[i + 1], '\0'}, 0, 16);

    更高级的代码将测试非十六进制字符或奇数/零长度的意外存在。


需要更改 CRC 计算

  • 将 CRC 计算更改为基于长度的计算而不是基于字符串的计算。

    // unsigned int crc32(const char *)
    unsigned int crc32(const void *m, size_t len)

    虽然下面没有编码,但在 crc32() 中考虑 uint32_t 而不是 unsigned int 以在 unsigned 时正确操作> 不是 32 位的。


总计

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

unsigned int crc32(const void *m, size_t len) {
const unsigned char *message = m;
size_t i;
int j;
unsigned int byte, crc, mask;

i = 0;
crc = 0xFFFFFFFF;
//while (message[i] != 0) {
while (i < len) {
byte = message[i]; // Get next byte.
crc = crc ^ byte;
for (j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}

示例用法

int main() {
char str[] =
"47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000";
size_t len = strlen(str);
unsigned int crc = crc32(str, len);
printf("CRC: 0x%X\n", crc); // 0xB6BA014A instead of 0xBF6B57A2

size_t len2 = (len + 1) / 2;
unsigned char arr2[len2];
for (size_t i = 0; i < len; i += 2) {
arr2[i / 2] = strtoul((char[3]) {str[i], str[i + 1], '\0'}, 0, 16);
}
crc = crc32(arr2, len2);
printf("CRC: 0x%X\n", crc); // 0xB6BA014A instead of 0xBF6B57A2

return 0;
}

输出

CRC: 0xB6BA014A
CRC: 0xBF6B57A2

OP 原始代码具有未定义的行为,因为它使用 while (message[i] != 0) { 寻找空字符,但 memcpy( arr, str, strlen(str)); 未能提供。

关于c - 如何将无符号字符数组解释为十六进制数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53574214/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com