如何将无符号字符数组解释为十六进制数组?
How to interpret an unsigned char array as hex array?
我有一个无符号字符数组,我想计算它的 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 数组解释为十六进制数组。
F.ex.,这是计算CRC的结果:
输入:
"47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000"
- as 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], '[=10=]'}, 0, 16);
更高级的代码将测试非十六进制字符或 odd/zero 长度的意外存在。
需要更改 CRC 计算
将 CRC 计算更改为基于长度的计算而不是基于字符串的计算。
// unsigned int crc32(const char *)
unsigned int crc32(const void *m, size_t len)
虽然下面没有编码,但考虑 uint32_t
而不是 crc32()
中的 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], '[=13=]'}, 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));
未能提供。
我有一个无符号字符数组,我想计算它的 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 数组解释为十六进制数组。
F.ex.,这是计算CRC的结果:
输入:
"47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000"
- as 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], '[=10=]'}, 0, 16);
更高级的代码将测试非十六进制字符或 odd/zero 长度的意外存在。
需要更改 CRC 计算
将 CRC 计算更改为基于长度的计算而不是基于字符串的计算。
// unsigned int crc32(const char *) unsigned int crc32(const void *m, size_t len)
虽然下面没有编码,但考虑
uint32_t
而不是crc32()
中的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], '[=13=]'}, 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));
未能提供。