我有一个设备,可以将 CRC32 校验和添加到它发送的数据中。使用查找表计算如下:
uint32_t CrcFromBuffer(uint8_t* buffer, uint16_t lenght) {
uint32_t crc32 = 0xffffffff;
if (buffer == NULL) {
return 0;
} else {
while (lenght != 0) {
uint8_t crc32_table_index = ((uint8_t)(crc32) ^ (*buffer));
crc32 = crc32 >> 8;
crc32 = crc32_table[crc32_table_index] ^ crc32;
buffer++;
lenght--;
}
}
return ~crc32;
}
我使用的是 STM32F401 微 Controller ,它具有使用相同多项式计算 CRC 的硬件支持,但仅使用 32 位输入数据大小。如果数据长度是 4 字节的倍数,则效果很好。这是一个例子:
bool eight_bytes_random_crc() {
uint8_t array8[8] = {0xAB, 0x21, 0x32, 0x47, 0x01, 0xFF, 0x00, 0x99};
uint32_t array32[2] = {__RBIT(0x473221AB), __RBIT(0x9900FF01)}; // need to reverse bit order
uint32_t hard_crc = __RBIT(~HAL_CRC_Calculate(&hcrc, array32, 2)); // again reverse bits and negate the result
uint32_t soft_crc = CrcFromBuffer(array8, 8);
return hard_crc == soft_crc;
}
如何对长度不是 4 字节倍数的数据数组使用 STM32 硬件 CRC 支持?
我尝试强力搜索一个值,该值将为单个字节生成相同的 CRC,但在仅给出 0xAB 输入的情况下找不到获取该值的明显方法:
uint32_t one_byte_crc() {
uint8_t array8[1] = {0xAB};
uint32_t soft_crc = CrcFromBuffer(array8, 1);
for (uint32_t i = 0; i <= 0xFFFFFFFF; i++ ) {
uint32_t array32[1] = {__RBIT(i)};
uint32_t hard_crc = __RBIT(~HAL_CRC_Calculate(&hcrc, array32, 1));
if (hard_crc == soft_crc) {
return i; // gives 0xF7D1D97E
}
}
}
关于如何将 STM32 硬件 CRC 用于非 4 字节长度数据数组的倍数,有什么建议吗?
最佳答案
您唯一能做的就是 a) 使用硬件计算 CRC,最多为数据的四个字节的倍数,然后使用软件用最后 0 到 3 个字节完成 CRC,或者 b )使用硬件计算用零填充到四的倍数的所有数据的 CRC,然后使用反向 CRC 表取消计算 CRC 中的最后 0 到 3 个零。
最有效的方法可能是使用 a) 如果还剩 0 或 1 个字节,以及 b) 如果还剩 3 个字节,因此不计算 1 个字节。对于剩下 2 个字节,您会选择更快的一个,但我不确定会是哪一个。两种方式都可以。
关于c - 如何匹配适用于各种数据大小的 CRC32 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76030571/