今晚看了好久CRC,最后还有没有很明白。但是做为一个做工程的,有结果就好了。
我要用的不是标准的CRC公式,是X8+1这个,呵呵。下面开始总结。
CRC用到的主要是模2除法,开始看得一头雾水,只有把这个弄清楚了,后来才有了思路。才知道CRC的计算过程。(此处是重点,我费了很多劲儿理解,省去若干字。)不知道计算过程,程序是绝对不能看懂的。
还有这么一句话:多项式的MSB略去不记,因其只对商有影响而不影响余数。 就是说对于CRC-CCITT=X16+X12+X5+1,可以只用0x1021,bit16位的1不要了,只留下bit12、5、0。(参考一篇modbus的说明)
记住这两点,再参考下面一段话:
生成CRC-16校验字节的步骤如下:
①装如一个16位寄存器,所有数位均为1。
②该16位寄存器的高位字节与开始8位字节进行“异或”运算。运算结果放入这个16位寄存器。
③把这个16寄存器向右移一位。
④若向右(标记位)移出的数位是1,则生成多项式1010000000000001和这个寄存器进行“异或”
运算;若向右移出的数位是0,则返回③。
⑤重复③和④,直至移出8位。
⑥另外8位与该十六位寄存器进行“异或”运算。
⑦重复③~⑥,直至该报文所有字节均与16位寄存器进行“异或”运算,并移位8次。
⑧这个16位寄存器的内容即2字节CRC错误校验,被加到报文的最高有效位。
别的都是弯路,以上是最清楚的、实惠的解释了。本文最后,附上另一位网游的文章,也给我很大启发。
下面是成功的程序:
unsigned short crc(unsigned char *addr, int num)
{
int i;
while (num--)
{
crc8 ^= *addr++;
for (i = 0; i < 8; i++)
{
if (crc8 & 128)
{
crc8 <<= 1;
crc8 ^= 0x01; //1010 0000 0000 0001b
}
else
{
crc8 <<= 1;
}
}
}
return crc8;
}
另外这样也行:
unsigned short crc(unsigned char *addr, int num)
{
//unsigned short crc8 = 0xFF;
int i;
while (num--)
{
crc8 ^= *addr++;
for (i = 0; i < 8; i++)
{
if (crc8 & 1)
{
crc8 >>= 1;
crc8 ^= 0x80; //1010 0000 0000 0001b
}
else
{