0x8005=1000 0000 0000 0101B
0xA001=1010 0000 0000 0001B
对比两个二进制高低bai位正好是完du全相反的,CRC校验分为zhi正向校验与反向校验。正dao向校验高位在左,反向校验低位在左,比如正向CRC校验的数据为0xAF5D=1010 1111 0101 1101B与0x8005异或时应该是0xAF5D^0x8005,而要使用0xA001与数据进行校验也应该使0xAF5D高低位换顺序为0xBAF5=1011 1010 1111 0101B。正向校验使用左移位,反向校验使用右移位,其实原理是一样的,得看校验的数据高低位顺序。
请注意使用时高低位的区别,0X8005和0XA001实际上只是高低位互反,有些硬件的存储模式不一样,因为会根据情况调整使用的具体方法,算法并无本质区别,希望能帮到你。
一般电气、自动化仪表的crc16校验,多项式码选用16进制A001。
https://zhidao.baidu.com/question/185131161.html
附参考:
数据(16进制):01 03 61 00 00 02 CRC校验:F7 DB 多项式是A001H
附C语言实现代码:
-
#include <stdio.h>
-
int main(void)
-
{
-
unsigned short tmp = 0xffff;
-
unsigned short ret1 = 0;
-
unsigned char buff[6] = {0};
-
buff[0] = 0x01;
-
buff[1] = 0x03;
-
buff[2] = 0x61;
-
buff[3] = 0x00;
-
buff[4] = 0x00;
-
buff[5] = 0x02;
-
for(int n = 0; n < 6; n++){/*此处的6 -- 要校验的位数为6个*/
-
tmp = buff[n] ^ tmp;
-
for(int i = 0;i < 8;i++){ /*此处的8 -- 指每一个char类型又8bit,每bit都要处理*/
-
if(tmp & 0x01){
-
tmp = tmp >> 1;
-
tmp = tmp ^ 0xa001;
-
}
-
else{
-
tmp = tmp >> 1;
-
}
-
}
-
}
-
/*CRC校验后的值*/
-
printf("%X\n",tmp);
-
/*将CRC校验的高低位对换位置*/
-
ret1 = tmp >> 8;
-
ret1 = ret1 | (tmp << 8);
-
printf("ret: %X\n",ret1);
-
return 0;
-
}
输出结果:
-
F7DB
-
ret: DBF7
另外用CRC校验工具得到结果是相同的但是多项式却是8005,只有表中选项出上面结果,其他选线选择或不选结果是另外的。
01 03 61 00 00 02的CRC校验结果
01 03 61 00 00 02的倒序是40 00 00 86 C0 80
结果也不相同。也不是倒序。不知道为什么?
可能是字节倒序,但是整个字节流还是正序。涉及到字节大小端2021.6.1