crc-16 IBM,0x00 未考虑

crc-16 IBM, 0x00 not taken in consideration

我确实测试了我在网上找到的 crc-16/ibm 实现。当我用十六进制字节数组测试它时它工作正常但是如果我包含一些 0x00 值,那么它不会给出正确的结果。 这是它的代码

unsigned short ComputeCRC16(const unsigned char* buf, unsigned int len) {
    unsigned short crc = 0;
    for (unsigned int j = 0; j < len; j++)
    {
        unsigned char b = buf[j];
        for (unsigned char i = 0; i < 8; i++)
        {
            crc = ((b ^ (unsigned char)crc) & 1) ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
            b >>= 1;
        }
    }
    return crc;
}

我用这段代码测试了它:

int main() {

    //fe   b5     5f       f7
    unsigned char buf1[4096] = { 0xfe, 0xb5, 0x5f, 0xf7 };

    //fe   b5     00    5f     f7   00
    unsigned char buf2[4096] = { 0xfe, 0xb5, 0x00, 0x5f, 0xf7, 0x00 };

    int a = strlen(buf1);
    unsigned short res = ComputeCRC16(buf1, a);
    printf("res = %04x\n", res); //res : 7858, the result is correct

    int b = strlen(buf2);
    unsigned short res = ComputeCRC16(buf2, b);
    printf("res = %04x\n", res); //res : d781, the result is not correct
    return 0;                   //the correct result : 26EE
}

为了验证我使用这个网站的结果: https://www.lammertbies.nl/comm/info/crc-calculation

您的 CRC 例程给出了正确的结果。是你的测试错了。 strlen(p) returns p 处的第一个零字节之前有多少字节。对于 buf2,那是四个,而不是你想要的五个。对于 buf1 它甚至没有定义,因为在该数组之后内存中可以有任何内容。如果编译器碰巧在数组后放置零,您可能得到四个。

为了测试,您只需手动提供 len(buf1, 4), (buf2, 5).

顺便说一下,该代码可能会更有效率。它不必每次都用 b 进行测试。与 b 开始的异或运算具有相同的效果:

    crc ^= buf[j];
    for (unsigned char i = 0; i < 8; i++)
        crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;