0

我曾多次尝试根据理论编写自己的 CRC32 实现,但始终没有得到预期的结果。

今天我又做了一次尝试,不仅参考了理论,还参考了 Boosts 的实现。虽然我终于让它正常工作,但我不明白为什么它会这样工作。

我明白为什么 boost 会反转字节并反转结果,我知道为什么它的初始余数是 0xffffffff 并且结果应该与 0xffffffff 异或。这是标准。但是当它到达功能时ProcessBit,我被卡住了。

如何计算 CRC32 校验和的答案中?,我找到了一个完整的例子。所以我认为的实现ProcessBit看起来像这样:

void CRC32::ProcessBit(bool b)
{
/*
    x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxb : x curVal, b coming bit
    1 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy : y polynomial
*/
    if (_remainder & 0x80000000) {
        _remainder <<= 1;
        _remainder |= b;
        _remainder ^= polynomial;
    } else {
        _remainder <<= 1;
        _remainder |= b;
    }
}

由于多项式的第一位是 1,如果余数以位 1 开头,我将对它进行异或。但是这个实现会产生错误的结果。我跟踪了 Boost 中的代码以了解它是如何工作的,并编写了自己的代码:

void CRC32::ProcessBit(bool b)
{
    bool high = (_remainder & 0x80000000) ? true : false;
    _remainder <<= 1;
    if (high != b) {
        _remainder ^= polynomial;
    }
}

这个实现效果很好。但我不明白为什么。令我困惑的是,确定余数是否应与多项式异或的条件是:

“余数的第一位等于即将到来的位”。

而在“完整示例”中使用了另一个条件,即:

“余数的第一位是 1”。

另一个问题是;为什么在 Boost 的实现中不会在剩余部分的末尾附加即将到来的位。

编辑: 我已经解决了这个问题。它产生错误结果的原因是我误解了“初始值”的含义。

4

0 回答 0