我有一个无符号字符数组,我想计算其CRC32校验和。
CRC32函数还需要一个无符号的char指针,但是,它将数组解释为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,但无符号字符数组必须解释为十六进制数组。
F.ex。,这是计算出的CRC的结果:
输入:
"47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000"
答案 0 :(得分:2)
如何将无符号char数组解释为十六进制数组?
将字符串中的每对十六进制字符转换为一个字节值。下面的代码通过复合文字转换为3个字节的 string ,然后调用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)
尽管未在下面进行编码,但是当uint32_t
不是32位时,可以考虑使用unsigned int
中的crc32()
而不是unsigned
中的#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
输出
while (message[i] != 0) {
OP原始代码具有未定义的行为,因为它寻找带有memcpy(arr, str, strlen(str));
的空字符,但是{
"username" : "TestUsername",
"email" : "TestUsername@outlook.com",
"password" : "Password01",
"group" : "partial-permission"
}
无法提供一个空字符。