在学习mdobus过程中,曾遇到过CRC校验,之前一直不是很明白其原理,现在利用一点闲暇时间学习下。

不同别的校验方式,想弄明白CRC校验的原理以及程序实现过程还真得有点耐心,琢磨一下数学公式。

1.      什么是CRC校验

一句话总结:将需要传递的数据块看成一个信息多项式M(x),收发双方约定一个生成多项式G(x),最高阶数为r,利用模2除法计算M(x)左移r位后与G(x)两者的余数就是CRC校验数据R(x)(或Thebasic idea of CRC algorithms is simply to treat the message as an enormousbinary number, to divide it by another fixed binary number, and to make theremainder from this division the checksum)。

这样将M(x)左移r位后与CRC校验位拼接起来就是发送信息T(x)。

用数学公式来表达就是T(x) = M(x)• + R(x) 其中M(x)•= G(x)•Q(x)+ R(x)

可以看出,对于发送多项式T(x),一定是可以整除G(x)的,因为补了余数嘛。

是不是够明白了。

2.      计算步骤

(1). Choose a width W, and a poly G (of width W).

(2). Append W zero bits to the message. Call this M'.

(3). Divide M' by G using CRC MOD2 arithmetic. The remainder is thechecksum.

3.      什么是模2运算

一般数据的加减法是基于10进制计算,有进位和借位,与之不同的是MOD2 运算时是不考虑进位和借位的,这样本位计算对前后位都没有影响,这样MOD2运算位加减法就是“相同为0,相异为1”,而乘除法可以用加减法去表示,所以MOD2运算就等同于异或运算。

4.      CRC校验可以检测什么样的错误?

正常情况下,发送多项式T(x)mod G(x)=0,如果传输过程中发送错误,发送多项式变为T(x)+ E,T(x)mod G(x)=E,如果E是G(x)的倍数,这样的错误是检测不出来的,其他的错误都可以检测出来。这样就要找一个G(x)使其与系统噪声的相似程度尽量低。那么如何寻找一个合适的生产多项式使传输错误尽可能多的被检测出来就很重要了。

5.      常用生成多项式的选择

这里只需记住三个,主要是CRC16

CRC-16(美国):     G(x) =x16+x15+x2+1

CRC-CCITT(欧洲): G(x) =x16+x12+x5+1

CRC-32 (32,26,23,22,16,12,11,10,8,7,5,4,2,1,0) 主要用于以太网校验。

取16或32bit主要是为了适用于微型计算机的字长,方便计算。

6.      计算方法

CRC单字节计算方法就不多说了,按照定义即可,下面说说数据块的CRC生成过程。

CRC校验有三种计算方法,一是按位计算,二是按字节计算,三是按半字节计算。

①按位计算方法,又叫直接计算法。直接给出,虽然这个算法因为效率低实用性不高,但是对于CRC计算的理解还是很有帮助的。直接计算法就是实现CRC模2除法,并不是普通的模10除法。

1.Loadthe register with zero bits.(如果计算CRC-M,则选择一个寄存器长度为M)

2.Augmentthe message by appending W zero bits to the end of it. (将信息多项式右移M位,补M个0)

While(more message bits)

Begin

Shiftthe register left by one bit, reading the next bit of the

augmentedmessage into register bit position 0.

If(a 1 bit popped out of the register during step 3)

Register= Register XOR Poly.

(如果有1被移除就与生产多项式异或一次)

End

The register now containsthe remainder.

(最终寄存器中包含的余数就是CRC计算值)

可以使用以下C语言程序去解释:CRC-4,计算一个字节

#define CRC_WIDTH   4

#define CRC_POLY   3

//load data

data = 0x35;           //加载信息数据

//append W zeros to the data

data <<= CRC_WIDTH;    //数据右移4位

//initial the regs

regs = 0;              //移位寄存器

//processing

for(shift_bit=DATA_WIDTH+CRC_WIDTH; shift_bit>0;shift_bit--){

// shift

regs = (regs<<1)| ((data>>(shift_bit-1))&0x1); //将新数据的最高位移入寄存器

// xor

if(regs>>CRC_WIDTH)     regs = regs ^ CRC_POLY; //如果寄存器最高位为1,则进行异或计算,计算完成后regs中就是CRC4的值

}

②查表法

然而在实际应用中多使用查表法,推导过程很复杂,数学不好的话建议直接记住结论,也就是:本字节的CRC码等于上一字节的余式的CRC码的低 8位左移8位后,再加上上一字节CRC右移8位(也就是取高8位)和本字节之和(异或)所求的CRC码,可以表示为

unsigned short do_crc_table(unsignedchar *ptr,int len)
{
    unsigned short int crc;
   unsigned char da;
    crc=0;
   while(len--!=0) 
    {
       da=(unsignedshort)crc>>8;   
        crc<<=8;             
        crc^=crc_ta[da^*ptr];  
        ptr++;
      }
   return(crc);
}

以上算法实现了按字节进行计算校验值。在使用的时候,把计算出来的校验值放在最后两个字节里,将其发送出去,接收端对所有的数据进行相同的校验,如校验值为0我们则认为其数据没有出错。这个是按高位到低位的发送顺序时使用的校验方法。
在实际应用中,还有一种按低位到高位的发送方法(比如串口数据就是先发低位后高位),这样 ,就要进行反相的校验,但如果把数据反相,显然加大计算量,故可以使用相应的查表算法(数学推导)来进行计算。可以由以下算法实现(摘自linux)

u16crc16(u16 crc, u8 const *buffer, size_t len){

while (len--)

crc = (crc >> 8) ^crc16_table[(crc ^ *buffer++) & 0xff];

retrun crc;

}

CRC校验实现原理以及程序实现研究相关推荐

  1. 来搞清楚CRC校验的原理和实现

    在MIPI_CSI-2协议里payload数据的校验使用了CRC校验,但是关于CRC校验只知其一,或者说只知的还不到其一,因此非常有必要搞清楚它,自然的我搜查了一些博主的文章尝试得到答案,最终在知乎前 ...

  2. 【Verilog】CRC校验码生成器原理及verilog实现

    目录 一.CRC的基本原理 二.CRC生成步骤 2.1举个栗子 三.Verilog实现 四.参考资料 4.1 CRC在线计算器 一.CRC的基本原理 CRC :Cyclic Redundancy Ch ...

  3. CRC校验的原理及实现方法

    一.CRC校验介绍 循环冗余校验码(CRC),是一种常用的.具有检错.纠错能力的校验码,在早期的通信中运用广泛.循环冗余校验码常用于外存储器和计算机同步通信的数据校验.循环冗余校验是通过某种数学运算来 ...

  4. CRC校验码原理及自动生成源码

    CRC原理简介:https://mp.weixin.qq.com/s/RNHLZGPD9Ysbxb1FNDn6EA 自动生成源代码网址:https://www.easics.com/webtools/ ...

  5. 32位crc校验码程序_CRC码计算及校验原理的最通俗诠释

    CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注 ...

  6. 如何在html里加入验证码_如何把crc校验加入到对应的程序里?看高手怎么做

    我们现在已经搞清楚了crc校验的算法,本文我就向大家具体讲解一下如何把crc校验加入到我们的程序里. 1 .crc校验使用原理 crc校验在程序中运行的原理主要可以分为以下几步. 第一步:主站发送数据 ...

  7. tcp中的crc检验算法原理_CRC校验原理及其实现

    原文作者:王超的独立博客 出处:http://www.wangchaochao.top/2020/09/20/Principle-and-implementation-of-CRC/ 前言 最近的工作 ...

  8. 简单易懂的CRC校验原理阐述

    不要跑,CRC没这么难!(简单易懂的CRC原理阐述) 网上大多的教材都是面向大佬的很多细节原理都没有讲清楚,对于我们这些新萌菜鸟们实在太不友好了.于是我写一篇相对轻松易懂的博客,希望能对学习CRC的朋 ...

  9. 【RE】3 CRC校验原理及实现

    0 简介 循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可 ...

最新文章

  1. JS-DOM-元素节点
  2. “那个工作 10 年没跳槽的人,混不下去了”
  3. Arrays.sort 不区分大小写 排序
  4. python 随机数 随即字符 打乱元素顺序 random.randint()[uniform(), choice(), randrange(), shuffle(), sample()]
  5. php通过正则表达式下载图片到本地的实现代码,PHP通过正则表达式下载图片到本地的实现代码...
  6. 去空白符的大文本字符统计(洛谷P5015题题解,Java语言描述)
  7. 我一定要找到它FreeEIM
  8. 12v服务器电源改可调_赫尔槽试验电源的选择(修订版)
  9. 思博伦安全专家预测2017年民用和军用全球导航应用面临的更大风险
  10. 不需要的系统垃圾把它杀掉!
  11. CAM365|超高性价比CAM软件推荐
  12. 装完nvme固态经常蓝屏_NVME固态硬盘安装WIN7系统时蓝屏(0x000007B)怎么解决
  13. free-mybatis-plugin插件下载
  14. Sublime Text3中文版下载网址
  15. MySQL Workbench 已停止工作 错误模块名称: KERNELBASE.dll 异常代码: 0xe0434352 程序无法正常启动:( 0xc000007b)
  16. Two Sum (两数之和) - Hash Table (哈希表)
  17. Win10删除|修改鼠标右键快捷键快捷菜单的操作
  18. 工作中常用的linux命令
  19. 电脑拓展显示器软件显示不清晰问题
  20. 2021企业薪酬管理咨询设计七步曲

热门文章

  1. 简洁大方 APC移动电源开箱评测
  2. 施耐德APC 7921/7921B入门IP配置,(串口设置IP)
  3. Java随机生成姓名、邮箱、手机号码
  4. Unity刀光的实现
  5. 用AI导盲背包替代导盲犬?用OAK相机做的这款方案值得围观
  6. 图深度学习:成果、挑战和未来
  7. 小米官网——主页直接跳转登录页或注册页的制作(详细分析)
  8. 【LeetCode】76. 最小覆盖子串 (Java代码)
  9. 在短信骚扰方面不做逆来顺受
  10. Realtime_Multi-Person_Pose_Estimation训练踩坑