我正在逐位计算CCITT CRC-16位。我这样做是因为它是一个原型,后来应该被移植到VHDL并最终成为硬件,以检查串行比特流。
在网上,我找到了一个单比特CRC-16更新步骤代码。编写了一个测试程序,它可以工作。除了一件奇怪的事情:我必须从低位到高位提供一个字节的位。如果我这样做,我会得到正确的结果。
在CRC-16的CCITT定义中,比特应该从最高位到最低位喂入。我要计算CRC的数据流也是这种格式,所以我的当前代码对我来说有点无用。
我很困惑。我本来不希望错误地输入位能够起作用。
问题:为什么CRC可以编写为采用两种不同的位顺序,并且如何转换我的单比特更新代码,使其接受MSB优先的数据?
以下是相关代码(已删除初始化和最终检查以使示例简短):
在网上,我找到了一个单比特CRC-16更新步骤代码。编写了一个测试程序,它可以工作。除了一件奇怪的事情:我必须从低位到高位提供一个字节的位。如果我这样做,我会得到正确的结果。
在CRC-16的CCITT定义中,比特应该从最高位到最低位喂入。我要计算CRC的数据流也是这种格式,所以我的当前代码对我来说有点无用。
我很困惑。我本来不希望错误地输入位能够起作用。
问题:为什么CRC可以编写为采用两种不同的位顺序,并且如何转换我的单比特更新代码,使其接受MSB优先的数据?
以下是相关代码(已删除初始化和最终检查以使示例简短):
typedef unsigned char bit;
void update_crc_single_bit (bit * crc, bit data)
{
// update CRC for a single bit:
bit temp[16];
int i;
temp[0] = data ^ crc[15];
temp[1] = crc[0];
temp[2] = crc[1];
temp[3] = crc[2];
temp[4] = crc[3];
temp[5] = data ^ crc[4] ^ crc[15];
temp[6] = crc[5];
temp[7] = crc[6];
temp[8] = crc[7];
temp[9] = crc[8];
temp[10] = crc[9];
temp[11] = crc[10];
temp[12] = data ^ crc[11] ^ crc[15];
temp[13] = crc[12];
temp[14] = crc[13];
temp[15] = crc[14];
for (i=0; i<16; i++)
crc[i] = temp[i];
}
void update_crc_byte (bit * crc, unsigned char data)
{
int j;
// calculate CRC lowest bit first
for (j=0; j<8; j++)
{
bit b = (data>>j)&1;
update_crc_single_bit(crc, b);
}
}
编辑说明:由于这里存在一些混淆:我必须逐位计算CRC,并且对于每个字节,要先处理最高有效位(MSB)。我不能简单地存储位,因为上面显示的代码是将要进入硬件的原型。
如果我按照以下顺序(显示接收到的比特位索引。每个字节都是先传输 MSB)输入比特流,则上面显示的代码将生成正确的结果:
|- first byte -|- second byte -|- third byte
7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,....
我需要将单个更新循环进行转换,以使其使用自然顺序(例如,按照接收顺序)生成相同的CRC:
|- first byte -|- second byte -|- third byte
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,....