1

取自 IEEE 802.3,

在数学上,对应于给定 MAC 帧的 CRC 值由以下过程定义:

a) 帧的前 32 位被补码。
b) 受保护字段的 n 位然后被认为是次数为 n – 1 的多项式 M(x) 的系数。(目标地址字段的第一位对应于 x(n–1) 项和MAC 客户端数据字段(或填充字段,如果存在)的最后一位对应于 x0 项。)
c) M(x) 乘以 x32 并除以 G(x),产生度数 ≤ 的余数 R(x) 31.
d) R(x) 的系数被认为是一个 32 位序列。
e) 对位序列进行补码,结果为 CRC。

https://www.kernel.org/doc/Documentation/crc32.txt

以这种方式编写的大端 CRC 编码如下:

for (i = 0; i < input_bits; i++) {
    multiple = remainder & 0x80000000 ? CRCPOLY : 0;
    remainder = (remainder << 1 | next_input_bit()) ^ multiple;
}

c)部分在哪里M(x) 乘以 x^32我没有看到任何数字附加了 32 个零。

以下代码对我来说也毫无意义。代码和数学并不真正匹配。

评估 CRC-32 实现的差异

unsigned short
crc16_update(unsigned short crc, unsigned char nextByte)
{
    crc ^= nextByte;

    for (int i = 0; i < 8; ++i) {
        if (crc & 1)
            crc = (crc >> 1) ^ 0xA001;
        else
            crc = (crc >> 1);
    }

    return crc;
}

这些实现在做什么?它们都没有真正类似于原始程序。

即使在阅读完这篇文章的最后它仍然没有意义: http ://www.relisoft.com/science/crcmath.html

4

1 回答 1

1

本教程(对于那些会抱怨链接失效的人来说也是这里这里这里),特别是“10. A Slightly Mangled Table-Driven Implementation”,很好地解释了优化以避免在最后提供额外的 32 个零位。

底线是您将位输入寄存器的末尾而不是开头,这与在末尾输入寄存器长度的零值具有相同的效果。

本教程还很好地展示了您引用的实现如何实现对 GF(2) 的长除法。

于 2014-06-21T17:12:15.377 回答