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

参考:CRC校验原理及实现 - 知乎 (zhihu.com)

CRC校验(一)——原理 - 菜鸟学院 (noobyard.com)

CRC码计算及校验原理的最通俗诠释 - 苦涩的茶 - 博客园 (cnblogs.com)

目录

  • 前言
  • CRC算法简介
  • CRC计算
  • CRC校验
  • CRC计算的verilog语言实现
  • CRC计算工具
  • 总结

前言

最近的工作中要实现对通信数据的CRC计算。因此花时间好好研究了一下周末有时间整理笔记。

一个完整的数据帧通常由一下部分构成:

校验位是为了保证数据在传输的过程中的完整性,采用一种指定的算法对原始的数据进行计算,得出的一个校验值,在接收方接收到数据时,采用同样的校验算法对原始的数据进行计算,如果计算结果和接收到的校验值一致,说明数据校验正确,这一帧数据可以使用。如果不一致,说明传输过程中出现了差错,这一阵数据丢弃,请求重新发送。

常用的校验算法有奇偶校验,校验和,CRC,还有LRC,BBC等不常用的校验算法。

以串口通信中的奇校验为例,如果数据中1的个数位奇数,则奇校验位为0,否则为1。

例如原始数据为:0001 0011,数据中1的个数(或各位相加)为3,所以奇校验位为0,这种校验方法很简单,但是这种校验方法有很大的误码率,假设由于传输过程中的干扰,接受断接受到的数据是0010 0011,通过奇校验原酸,得到奇校验位的值为0,虽然校验通过,但是数据已经发生了错误。

校验和同理也会有类似的错误:

一个好的校验方法,配合数字信号编码方式,如(差分)曼彻斯特编码,(不)归零码等对数据进行编码,可大大提高通信的健壮性和稳定性,例如以太网中使用的是CRC-32校验,本文介绍CRC校验的原理和实现方法。

CRC算法简介

循环冗余校验(Cyclic Redundancy check,CRC)是一种根据网络数据包或计算机文件等书记产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误,它是利用除法以及余数的原理来做错误帧检测的。

CRC校验计算速度快,检错能力强,易于用编码器等硬件电路实现,从检错的正确率与速度成本等方面,都比奇偶校验方式具有优势,因而,CRC成为计算机信息通信领域最为普遍的校验方式,常见应用有以太网/USB通信,压缩解压,视频编码,图像存储,磁盘读写等。

CRC参数模型

不知道你是否遇到过这种情况,同样的CRC多项式,调用不同的CRC计算函数,得到的结果却不一致,而且和手算的结果也不一样,这就涉及到CRC的参数模型了,计算一个正确的CRC值,需要知道CRC的参数模型。

一个完整的CRC参数模型应该包含一下信息:WIDTH, POLY, INIT, REFIN, REFOUT, XOROUT

  • NAME:参数模型名称
  • WIDTH: 宽度,即生成的CRC数据宽度,如CRC-8,生成CRC为8位
  • POLY:十六进行多项式,省略最高位1,如X^8+X^2+X+1,二进制为1 0000 0111,省略最高位1,转换为16进制为0x07。
  • INIT:CRC初始值,和WIDTH位宽一致。
  • REFIN:true或者false,在进行计算前,原始数据是否翻转,eg:原始数据0x34 = 0011 0100
  • 如果REFIN为ture,进行反转之后为0010 1100 = 0x2c
  • REFOUT:true或者false,运算完成后,得到的CRC值是否进行翻转,如计算得到的CRC值为:
  • 0x97 = 1001 0111,如果REFOUT为ture,进行翻转后为1110 1001 = 0xE9
  • XOROUT:计算结果与此参数进行异或运算后得到最终的CRC值,和WIDTH位宽一致。

PS:首先把生成多项式转换成二进制数,由G(X) = X^8 + X^2 +X+1可以知道(它一共是9位(总位数等于最高位的幂次加1,即8+1=9),然后根据多项式各项的含义(多项式只列出二进制值为1的位,也就是这个二进制的第8位、第3位、第1位、第0位的二进制均为1,其它位均为0)很快就可得到它的二进制比特串为1 0000 0111)

参考了:CRC码计算及校验原理的最通俗诠释 - 苦涩的茶 - 博客园 (cnblogs.com)

通常如果只给了一个多项式,其他的没有说明,则默认:INIT:0x00,REFIN=false,REFOUT=false,XOROUT=0x00

常用的21个标准CRC参数模型:

CRC算法名称 多项式公式 宽度 多项式 初始值 结果异或值 输入反转 输出反转
CRC-4/ITU x4 + x + 1 4 03 00 00 true true
CRC-5/EPC x5 + x3 + 1 5 09 09 00 false false
CRC-5/ITU x5 + x4 + x2 + 1 5 15 00 00 true true
CRC-5/USB x5 + x2 + 1 5 05 1F 1F true true
CRC-6/ITU x6 + x + 1 6 03 00 00 true true
CRC-7/MMC x7 + x3 + 1 7 09 00 00 false false
CRC-8 x8 + x2 + x + 1 8 07 00 00 false false
CRC-8/ITU x8 + x2 + x + 1 8 07 00 55 false false
CRC-8/ROHC x8 + x2 + x + 1 8 07 FF 00 true true
CRC-8/MAXIM x8 + x5 + x4 + 1 8 31 00 00 true true
CRC-16/IBM x16 + x15 + x2 + 1 16 8005 0000 0000 true true
CRC-16/MAXIM x16 + x15 + x2 + 1 16 8005 0000 FFFF true true
CRC-16/USB x16 + x15 + x2 + 1 16 8005 FFFF FFFF true true
CRC-16/MODBUS x16 + x15 + x2 + 1 16 8005 FFFF 0000 true true
CRC-16/CCITT x16 + x12 + x5 + 1 16 1021 0000 0000 true true
CRC-16/CCITT-FALSE x16 + x12 + x5 + 1 16 1021 FFFF 0000 false false
CRC-16/X25 x16 + x12 + x5 + 1 16 1021 FFFF FFFF true true
CRC-16/XMODEM x16 + x12 + x5 + 1 16 1021 0000 0000 false false
CRC-16/DNP x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1 16 3D65 0000 FFFF true true
CRC-32 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 32 04C11DB7 FFFFFFFF FFFFFFFF true true
CRC-32/MPEG-2 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 32 04C11DB7 FFFFFFFF 00000000 false false

CRC校验在电子通信领域非常常用,可以说有数据处理的地方就有CRC校验:

举几个例子:

  • 美信(MAXIM)的芯片DS2401/DS18B20,都是使用的CRC-8/MAXIM模型
  • SD卡或MMC使用的是CRC-7/MMC模型
  • Modbus通信协议使用的是CRC-16/MODBUS参数模型
  • USB协议中使用的是CRC-5/USB和CRC-16/USB模型
  • STM32自带的硬件CRC计算模块使用的是CRC-32模型

至于多项式的选择,初始值和异或值得选择,输入输出是否翻转,这就这几到一定得编码和数学知识了,感兴趣得朋友可以了解一下每个CRC模型个个参数得来源,至于每种参数模型得检错能力,重复率,需要专业的数学计算了,不在本文讨论的范围内。

CRC计算

好了,了解了CRC参数模型知识,下面手算一个CRC值,来了解CRC计算的原理。

问:原始数据0x34,使用CRC-8/MAXIN参数模型,求CRC值?

答:根据CRC参数模型表,得到CRC-8/MAXIN的参数如下:

POLY = 0x31 = 0011 0001(最高位1已经省略)
INIT = 0x00
XOROUT = 0x00
REFIN = TRUE
REFOUT = TRUE

注意:原始数据和参数中的INIT值不是一个东西!!!

有了上面的参数,这样计算条件才算完整,下面来实际计算:

  • 0:原始数据= 0x34 = 0011 0100 , POLY=0x31 = 1 0011 0001
  • 1:INIT = 0x00,原始数据和初始值进行异或运算保持不变
  • 2:REFIN为true,需要先对原始数据进行翻转:0011 0100 ——> 00101100
  • 3:原始数据左移8位,即后面补8个0:0010 1100 0000 0000
  • 4:把处理后的数据和多项式进行模2除法,求得余数

原始数据:0010 1100 0000 0000 = 10 1100 0000 0000

多项式:1 0011 0001

模2除法取余数低8位:1111 1011

  • 5:与XOROUT进行异或,1111 1011 xor 0000 0000 = 1111 1011
  • 6:因为REFOUT为TRUE,对结果进行翻转得到最终的CRC-8值:1101 1111 = 0xDF
  • 7:数据+CRC :0011 0100 1101 1111 = 0x34DF,相当于原始数据左移8位+余数

看到这里细心的同学肯定会有疑问:

1:为什么step1,原始数据和初始值异或运算保持不变 ?

答:算法规定在进行上述模2运算之前,需要先将要计算的数据与初始值进行异或,然后再与多项式进行计算。

2:为什么要将原始数据左移8位 ?

答:暂时不清楚,这里有提到左移的规则,但是有待商榷

不要跑,CRC没这么难!(简单易懂的CRC原理阐述) - SegmentFault 思否

实验1:

如上所述,对原始数据0x34的模2除法过程如图中所示:

实验二:

对原始数据0xc,使用CRC-4/ITU参数模型,求CRC值?

与手算结果一致。

 CRC校验

上面通过笔算的方式,讲解了CRC计算的原理,下面来介绍一下如何进行校验。

按照上面CRC计算的结果,最终的数据帧:0011 0100 1101 1111 = 34DF,前8位0011 0100是原始数据,后8位1101 1111 是 CRC结果。

接收端的校验有两种方式,一种是和CRC计算一样,在本地把接收到的数据和CRC分离,然后在本地对数据进行CRC运算,得到的CRC值和接收到的CRC进行比较,如果一致,说明数据接收正确,如果不一致,说明数据有错误。

另一种方法是把整个数据帧进行CRC运算,因为是数据帧相当于把原始数据左移8位,然后加上余数,如果直接对整个数据帧进行CRC运算(除以多项式),那么余数应该为0,如果不为0说明数据出错

附上在线CRC校验计算器:

CRC(循环冗余校验)在线计算_ip33.com

来搞清楚CRC校验的原理和实现相关推荐

  1. CRC校验实现原理以及程序实现研究

    在学习mdobus过程中,曾遇到过CRC校验,之前一直不是很明白其原理,现在利用一点闲暇时间学习下. 不同别的校验方式,想弄明白CRC校验的原理以及程序实现过程还真得有点耐心,琢磨一下数学公式. 1. ...

  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. 简单易懂的CRC校验原理阐述

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

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

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

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

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

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

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

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

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

最新文章

  1. python核心编程学习(第四章)
  2. 网络通信应用开发利器!—— ESPlus —— ESFramework通信框架的增强库
  3. ARP缓存记录种类动态条目和静态条目
  4. shell 学习笔记(18)
  5. The RSpec Book笔记《一》初步认识TDD,BDD,RSpec,Cucumber
  6. 【Deep Learning】Tensorflow实现逻辑回归
  7. c语言实现字符指针(字符串)数组的排序
  8. eclipse maven 构建简单springmvc项目
  9. android用java写文本框_Android 自动完成文本框的实例
  10. SDUT 1157-小鼠迷宫问题(BFSamp;DFS)
  11. HDU-2063-过山车(二分匹配)
  12. 微信小程序:动画效果集合
  13. iOS/Android开发人脸识别SDK列表
  14. 简单分析大量京东快递揽收后没有物流的单号
  15. 004---css样式表(内部样式表、行内样式表、外部样式表)
  16. 目前软搭建测试的行业现状和前景
  17. “500 - 内部服务器错误。”解决办法
  18. 指针:const与指针
  19. 中琅条码软件连续打印设置方法
  20. Beta阶段事后诸葛亮分析

热门文章

  1. 单相干式变压器红外图像数据集
  2. 白帽子学习——Metasploit渗透测试指南
  3. 招聘中求职者关心哪些问题?
  4. SettingsProvider简单分析
  5. tomcat与servlet共存时报错 org.apache.catalina.LifecycleException:
  6. 中国古代数学家张丘建在他的《算经》中提出了一个著名的 “ 百钱买百鸡问题”鸡翁一, 值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何
  7. 计算机应用基础第1版前言,《计算机应用基础课件》前言
  8. EF更新使用AutoMapper_se7en3_新浪博客
  9. dhcp服务器显示不启用,如何启用dhcp服务器
  10. Python 百天读书笔记 | 字符串和常用数据结构 7day