如何在结构上计算 crc16

C.W*_*.W. 1 c struct crc16

我最近阅读了一些关于 crc 计算的论文和代码(例如A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMSLinux 中的实现)。据我了解,crc 是从某个地址开始逐字节完成的。

来自 Linux 内核的示例:

u16 crc16(u16 crc, u8 const *buffer, size_t len)
{
    while (len--)
    crc = crc16_byte(crc, *buffer++);
    return crc;
}
Run Code Online (Sandbox Code Playgroud)

现在我问自己是否可以使用struct?

unw*_*ind 5

如果你想要一个合理的结果,一般不会,不。

这是因为 CRC 应该是在“已知”字节序列上计算的,而内存中的结构不是已知字节序列。可以有用于对齐目的的填充字节,您不一定知道或控制它们,当然,struct在不同的系统/平台上,各种字段可以具有不同的大小(就像它本身一样)。

如果您首先可以使用已知且稳定的映射将结构序列化为字节序列,那么您当然可以将 CRC 应用于该序列。这是(巧妙地)由buffer参数is 暗示的const u8 *,即指向常量字节的指针,而不是const void *

如果您不关心,并且不介意(例如)更改编译器设置和/或将程序移动到不同的系统,则可以使用:

const struct mystruct s = { ... };
const u16 crc = crc16(0, (u8 *) &s, sizeof s);
Run Code Online (Sandbox Code Playgroud)

但这包括结构中的任何填充,因此非常危险。