CRC校验8/16/32全搞定

话不多说,先传代码:

vs2003可直接运行,非查表法,追求效率不建议采用。使用灵活,可以设置初值,可以按照自己的想法设定自己的标准多项式。http://download1.csdn.net/down3/20070609/09122755709.rar

crc8校验查表法实现方法,对大家理解查表法很有帮助。http://download1.csdn.net/down3/20070609/09122846704.c

Java实现的CRC校验,和C使用相同的方法,只是语言不同。包含现高位后低位16位校验方法,不过标准多项式要写成0x1021(CCITT),0x8005(CRC-16)。http://download1.csdn.net/down3/20070609/09122906382.java

8/16/32位CRC校验表,校验初值为零,先低位后高位的校验结果,可以核对下自己的算法对不对。http://download1.csdn.net/down3/20070609/09122931660.txt

自己的,别人的,总结来的,黑猫白猫希望对大家有帮助 !

/*****************************************************************************************************/

下面我对校验一些理解,都是参考别人的:

原理:采用CRC 校验时,发送方和接收方用同一个生成多项式g(x),并且g(x)的首位和最后一
位的系数必须为1。CRC 的处理方法是:发送方以g(x)去除t(x),得到余数作为CRC 校验码。
校验时,以计算的校正结果是否为0 为据,判断数据帧是否出错。听起来很简单!

步骤:CRC 校验码的编码方法是用待发送的二进制数据t(x)除以生成多项式g(x),将最后的余数
作为CRC 校验码。其实现步骤如下:
(1) 设待发送的数据块是m 位的二进制多项式t(x),生成多项式为r 阶的g(x)。在数据块
的末尾添加r 个0,数据块的长度增加到m+r 位,对应的二进制多项式为) (x t xr 。
(2) 用生成多项式g(x)去除) (x t xr ,求得余数为阶数为r-1 的二进制多项式y(x)。此二进
制多项式y(x)就是t(x)经过生成多项式g(x)编码的CRC 校验码。
(3) 用) (x t xr 以模2 的方式减去y(x),得到二进制多项式) ( ' x t xr 。) ( ' x t xr 就是包含了CRC
校验码的待发送字符串。依然简单。

根据上面的原理和步骤按照加减乘除算出的结果肯定是错误的,因为CRC采用的是模二运算。Spark Huang(hcpp@263.net)的文章(Spark Huang's Blog(http://blog.csdn.net/hqw))解答我的疑惑:CRC算法的是以GF(2)(2元素伽罗瓦域)多项式算术为数学基础的,GF(2)多项式中的加减用模2算术执行对应项上系数的加减,模2就是加减时不考虑进位和借位,就是异或运算。按照这个运算法则再根据上面的步骤,试试能不能算出0x01的校验码,很麻烦的,很有趣的,哈哈!

先高后低和先低后高的运算是刚好相反地,用先高后低的方式很容易理解CRC的原理,但实际上大多都用先低后高DS18B20,MODBUS,CCITT都这样用。先高后低算法中多项式左移,判断高位是否为1;先低后高算法中多项式右移,判断低位是否为1,为1右移一位与0x8C(8位CRC)异或,或者与0x115异或再右移一位;算法实现的过程是个模二运算的除法过程,不过不管商,只要余数(校验码)。

校验码的位数是和标准多项式特征码的位数一样的,余数和除数的位数一样。

因为校验码的计算过程是右移或者左移加上异或的过程,根据异或的交换率,我们可以将校验码的计算拆分开计算,CRC(A^B)=CRC(A)^CRC(B)。CRC(0xFF)=CRC(0x0F)^CRC(0xF0)=0x(0x80)^0x(0x40)^0x(0x20)^0x(0x10)^0x(0x08)^0x(0x04)^(0x02)^0x(0x01),这也是简化查表法的原理。先高位后低位按字节校验,CRC(0x1234)=CRC(0x1200)^CRC(0x34)=(CRC(0x12)<<8)^CRC(0x34);先低位后高位按字节校验,CRC(0x1234)=CRC(0x3400,0x12)=CRC(0x3400)^CRC(0x12)=(CRC(0x34)>>8)^CRC(0x12)。

另外{0x01}的CRC8校验0x5E,{0x01, 0x5E}的校验为零,即加上检验码的多项式校验为零,这可以作为CRC校验判断依据。而且初始值为零的校验在被校验码前加零,校验码不变,{0x01}={0x00,0x00,0x01},这也是CRC要将初值设置成0xFFFF的原因。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值