2019独角兽企业重金招聘Python工程师标准>>>

循环冗余检验 (CRC) 算法原理

Cyclic Redundancy Check循环冗余检验,是基于数据计算一组效验码,用于核对数据传输过程中是否被更改或传输错误。

算法原理

假设数据传输过程中需要发送15位的二进制信息g=101001110100001,这串二进制码可表示为代数多项式g(x) = x^14 + x^12 + x^9 + x^8 + x^7 + x^5 + 1,其中g中第k位的值,对应g(x)中x^k的系数。将g(x)乘以x^m,既将g后加m个0,然后除以m阶多项式h(x),得到的(m-1)阶余项r(x)对应的二进制码r就是CRC编码。

h(x)可以自由选择或者使用国际通行标准,一般按照h(x)的阶数m,将CRC算法称为CRC-m,比如CRC-32、CRC-64等。国际通行标准可以参看http://en.wikipedia.org/wiki/Cyclic_redundancy_check

g(x)和h(x)的除运算,可以通过g和h做xor(异或)运算。比如将11001与10101做xor运算:

明白了xor运算法则后,举一个例子使用CRC-8算法求101001110100001的效验码。CRC-8标准的h(x) = x^8 + x^7 + x^6 + x^4 + x^2 + 1,既h是9位的二进制串111010101。

经过迭代运算后,最终得到的r是10001100,这就是CRC效验码。

通过示例,可以发现一些规律,依据这些规律调整算法:

1. 每次迭代,根据gk的首位决定b,b是与gk进行运算的二进制码。若gk的首位是1,则b=h;若gk的首位是0,则b=0,或者跳过此次迭代,上面的例子中就是碰到0后直接跳到后面的非零位。

2. 每次迭代,gk的首位将会被移出,所以只需考虑第2位后计算即可。这样就可以舍弃h的首位,将b取h的后m位。比如CRC-8的h是111010101,b只需是11010101。

3. 每次迭代,受到影响的是gk的前m位,所以构建一个m位的寄存器S,此寄存器储存gk的前m位。每次迭代计算前先将S的首位抛弃,将寄存器左移一位,同时将g的后一位加入寄存器。若使用此种方法,计算步骤如下:

※蓝色表示寄存器S的首位,是需要移出的,b根据S的首位选择0或者h。黄色是需要移入寄存器的位。S'是经过位移后的S。

查表法

同样是上面的那个例子,将数据按每4位组成1个block,这样g就被分成6个block。

下面的表展示了4次迭代计算步骤,灰色背景的位是保存在寄存器中的。

经4次迭代,B1被移出寄存器。被移出的部分,不我们关心的,我们关心的是这4次迭代对B2和B3产生了什么影响。注意表中红色的部分,先作如下定义:

B23 = 00111010
   b1 = 00000000
   b2 = 01010100
   b3 = 10101010
   b4 = 11010101
   b' = b1 xor b2 xor b3 xor b4

4次迭代对B2和B3来说,实际上就是让它们与b1,b2,b3,b4做了xor计算,既:

B23 xor b1 xor b2 xor b3 xor b4

可以证明xor运算满足交换律和结合律,于是:

B23 xor b1 xor b2 xor b3 xor b4 = B23 xor (b1 xor b2 xor b3 xor b4) = B23 xor b'

b1是由B1的第1位决定的,b2是由B1迭代1次后的第2位决定(既是由B1的第1和第2位决定),同理,b3和b4都是由B1决定。通过B1就可以计算出b'。另外,B1由4位组成,其一共2^4有种可能值。于是我们就可以想到一种更快捷的算法,事先将b'所有可能的值,16个值可以看成一个表;这样就可以不必进行那4次迭代,而是用B1查表得到b'值,将B1移出,B3移入,与b'计算,然后是下一次迭代。

可看到每次迭代,寄存器中的数据以4位为单位移入和移出,关键是通过寄存器前4位查表获得
,这样的算法可以大大提高运算速度。

上面的方法是半字节查表法,另外还有单字节和双字节查表法,原理都是一样的——事先计算出2^8或2^16个b'的可能值,迭代中使用寄存器前8位或16位查表获得b'。

反向算法

之前讨论的算法可以称为正向CRC算法,意思是将g左边的位看作是高位,右边的位看作低位。G的右边加m个0,然后迭代计算是从高位开始,逐步将低位加入到寄存器中。在实际的数据传送过程中,是一边接收数据,一边计算CRC码,正向算法将新接收的数据看作低位。

逆向算法顾名思义就是将左边的数据看作低位,右边的数据看作高位。这样的话需要在g的左边加m个0,h也要逆向,例如正向CRC-16算法h=0x4c11db8,逆向CRC-16算法h=0xedb88320。b的选择0还是h,由寄存器中右边第1位决定,而不是左边第1位。寄存器仍旧是向左位移,就是说迭代变成从低位到高位。

转载于:https://my.oschina.net/u/138598/blog/119357

【数据校验杂谈】循环冗余检验 (CRC) 算法原理相关推荐

  1. CRC算法原理及其Verilog实现

    CRC算法原理及其Verilog实现 2015-03-19 21:28  688人阅读  评论(0)  收藏  举报   分类: FPGA基础知识(39)  http://blog.163.com/f ...

  2. c语言 x16 x15 x2 1,CRC算法原理及C语言实现

    CRC算法原理及C语言实现 摘 要 本文从理论上推导出CRC算法实现原理,给出三种分别适应不同计算机或微控制器硬件环境的C语言程序.读者更能根据本算法原理,用不同的语言编写出独特风格更加实用的CRC计 ...

  3. 循环冗余检验 CRC

    一.总体流程: 把要发送的每组数据2^nM(k+n位)除以除数P(n+1位),计算出冗余码FCS(n位),然后再求出要发送的数据:2^nM+R. 接受端把收到的数据除以除数P,看余数R是否为0,如果为 ...

  4. 循环冗余检验CRC原理

    为什么引入CRC 现实的通信链路都不会是理想的.这就是说,比特在传输的过程中可能会产生差错:1可能会变成0,0可能会变成1,这就叫做比特差错.在一段是时间内,传输错误的比特占所传输比特总数的比率成为误 ...

  5. 数据降维--------主成分分析(PCA)算法原理和实现学习笔记

    1 主成分分析背景 '''PCA计算步骤(思想是把数据投影到方向向量使数据集的特征向量到方向向量的垂线长度最短) 1.去平均 2.计算协方差矩阵 3.计算协方差矩阵的特征向量和特征值 4.将特征值从小 ...

  6. crc校验matlab编码流程图,crc校验matlab

    关键词: MATLAB;C 语言 ;CRC 循环冗余校验码 2 1.概要 1.1... 结果:出错了 七.思考题 1.掌握按字节编码的过程,试着写出CRC 校验编码的Matlab 程序? %main ...

  7. 常用算法 之五 数据校验(CRC 原理、LRC、奇偶校验、校验和)详解

    数据校验   数据在传输的过程中,会受到各种干扰的影响,如脉冲干扰,随机噪声干扰和人为干扰等,这会使数据产生差错.为了能够控制传输过程的差错,通信系统必须采用有效措施来控制差错的产生,并保证数据的完整 ...

  8. C语言 crc32校验算法原理,CRC循环冗余校验的实现原理

    之前在做学校项目的时候用到了CRC 原理,但在网上查找的过程中,发现讲解CRC知识的资源很多,但是对新手比较友好的.讲的十分清楚的又很少,很多资料也不完善,读起来心中常常不由自主地奔腾过上千个&quo ...

  9. CRC算法 个人学习笔记 直接法、查表法注意点

    CRC检验码主要是用在数据校验中,用于判断对应数据是否发生传输错误,详细的介绍百度就可以.本文主要是记录我个人在这几天学习使用CRC的过程中遇到的问题.各位在阅读时如果有发现问题,可在评论区留言,谢谢 ...

最新文章

  1. Uploadify jquery+falsh+UploadHandler.ashx
  2. 关于vs生成app错误提示,提醒Execution failed for task ':transformClassesWithDexForDebug'.
  3. POJ - 2828 Buy Tickets(线段树+思维/Splay+模拟)
  4. .net core HttpContext(Http上下文)
  5. C#方法的参数 Ref Out Params 4种类型的参数
  6. Theano2.1.10-基础知识之循环
  7. 学习Web前端,前景无限光明?
  8. 如何利用OTDR光纤测试仪定位熔接点及诊断排除故障
  9. 毕业设计-基于汇编语言的at89c52单片机可调数字钟的设计,基于AT89S52单片机数字钟的仿真设计(汇编语言程序)...
  10. EGO1—实现计数器74HC163
  11. Link warning:LNK4199 解决
  12. 08-微信公众号素材管理
  13. json发送数据加密方法_发送加密的电子邮件和安全邮件的最佳免费方法
  14. php根据ip地址查询经纬度,根据IP查询经纬度
  15. 软件质量的定义及其六大特性(质量模型)
  16. 这五款牛逼的 IDEA 插件,堪称代码质量检查利器!
  17. 塞瓦定理,逆定理,及其引伸的证明
  18. Leetcode—— 104. 二叉树的最大深度
  19. java调用mysql数据库的基本操作方法
  20. Ubuntu下升级安装gcc-7.5.0

热门文章

  1. Java 线程池ThreadPoolExecutor的应用与源码解析
  2. SpringBoot 精通系列-如何优雅地使用Mybatis的XML配置
  3. hash表冲突处理方法
  4. IDEA 在头注解上添加用户名称和时间
  5. 问题:使用jdk11 报错:java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present
  6. 最小安装下如何打开网络连接
  7. kafka指定分区消费
  8. java多叉树的遍历
  9. 我来重新学习 javascript 的面向对象(part 1)
  10. 总结php删除html标签和标签内的内容的方法