CRC - 使用不同多项式符号的16位查找表

时间:2015-06-30 07:31:54

标签: c crc

我正在使用16位CRC并且有一个查找表(LUT)生成器,它为给定的多项式生成LUT。我使用的生成器代码使用Koopman表示法(例如,对于CCITT为0x8810),因此产生第一个表行:

 0x0000, 0x8810, 0x9830, 0x1020, 0xB870, 0x3060, 0x2040, 0xA850,

我发现一个已经计算好的CCITT表在互联网上实现了,但显然使用了第一行的不同符号:

0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 

我的问题是:短符号和长符号(0x8810与0x11021)是否会在不同的表格中产生相同的结果(即LUT的使用不同),或者在不同的符号中使用相同的多项式会使CRC不同吗? / p>

ps:据我所知,0x8810和0x11021是非反射的考夫曼/“正常”符号,0x8408和0x10811是反射的(对于CCITT)

pps:第二个表的“使用代码”为:

uint16_t crc16_block(uint16_t crc, uint8_t *data, int len){
    int i;

    for (i = 0; i < len; i++)
        crc = (crc << 8) ^ crc16_tbl[(crc >> 8) ^ data[i]];

    return crc;
}

1 个答案:

答案 0 :(得分:2)

Koopman的符号表示多项式,但是多项式。您不能将它用作您使用的查找表生成器的输入。你的第一个表是无用的,因为隐含的多项式没有低位1。

Koopman的符号取决于所有CRC多项式以1结尾的事实。多项式总是具有 + 1 项。转换为二进制时,它们始终以1( x 的最高幂)开始,并始终以1结束。 10001000000100001或0x11021,用于CCITT多项式, x 16 + x 12 + x 5 +1 。< / p>

关于这个数字的烦人的事情是需要17位才能表示。您希望有一个仅使用16位的符号,以便更容易在具有16位整数的计算机程序中指定多项式(或类似地,需要32位而不是33位来指定32位CRC)。 / p>

有两种解决方案。掉高1,或降低1.通常你会看到高1下跌。即0x1021,加上你需要提供CRC的长度,在这种情况下为16。因此规范是16,0x1021。 (还有其他一些事情你需要指定,但是现在我们将自己限制在CRC和多项式的大小。)

Koopman意识到如果你改为删除 low 1,你甚至不需要指定长度,仍然指定16位的16位CRC多项式。你通过向下移动一个来降低低点1。所以0x11021变为0x8810。高1仍然存在,因此它隐含地定义了CRC的长度。

但是,要在Koopman表示法中使用 CRC,你必须将它向上移一个并加一个以获得计算的多项式和表格