参考资料

CRC校验原理及实现 - 知乎 (zhihu.com) <-- 这个讲的特别好,我的博客主要是抄他的,最后加了一点代码库的分析。

[CRC校验]手算与直观演示_哔哩哔哩_bilibili <-- 这个视频非常直观

【FPGA】CRC校验算法从数学原理到代码实现

CRC 参数模型

同样的 CRC 多项式,调用不同的 CRC 计算函数,得到的结果却不一样,这就涉及到 CRC 的参数模型了。计算一个正确的 CRC 值,需要知道 CRC 的参数模型。

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

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

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

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

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模型各个参数的来源。至于每种参数模型的检错能力、重复率,需要专业的数学计算了,不在本文讨论的范畴内。

对于 发送 和 接收 两方的约定

  1. 共同的约定

    • 要传输的数据的原始数据:比如8‘b10101001
    • 生成多项式
  2. 发送方要做的事(编码)
    • 准备要传输的原始数据
    • 根据 原始数据 和 生成多项式 生成 原始数据对应的 CRC
    • 生成新数据({原始数据,CRC})
  3. 接收方要做的事(解码)
    • 接收发送方发送过来的新数据
    • 根据新数据和约定好的生成多项式做校验
    • 根据校验结果接收原始数据

CRC 计算

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

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

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

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

0.原始数据 = 0x34 = 0011 0100,多项式 = 0x31 = 1 0011 0001
1.INIT = 00,原始数据高8位和初始值进行异或运算保持不变。
2.REFIN为TRUE,需要先对原始数据进行翻转:0011 0100 > 0010 1100
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 = 34DF,相当于原始数据左移8位+余数。

模2除法求余数:

验证手算结果:

可以看出是一致的,当你手算的结果和工具计算结果不一致时,可以看看INIT,XOROUT,REFINT,REFOUT这些参数是否一致,有1个参数不对,计算出的 CRC 结果都不一样。

CRC 校验

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

接收端的校验有两种方式,

  1. 一种是和 CRC 计算一样,在本地把接收到的数据和 CRC 分离,然后在本地对数据进行 CRC 运算,得到的 CRC 值和接收到的 CRC 进行比较,如果一致,说明数据接收正确,如果不一致,说明数据有错误。
  2. 另一种方法是把整个数据帧进行 CRC 运算,因为是数据帧相当于把原始数据左移8位,然后加上余数,如果直接对整个数据帧进行 CRC 运算(除以多项式),那么余数应该为0,如果不为0说明数据出错。

而且,不同位出错,余数也不同,可以证明,余数与出错位数的对应关系只与CRC参数模型有关,而与原始数据无关。

CRC 计算的 C 语言实现

无论是用C还是其他语言,实现方法网上很多,这里我找了一个基于C语言的CRC计算库,里面包含了常用的21个CRC参数模型计算函数,可以直接使用,只有crcLib.ccrcLib.h两个文件。

GitHub地址:https://github.com/whik/crc-lib-c

使用方法非常简单:

#include <stdio.h>
#include <stdlib.h>
#include "crcLib.h"int main()
{uint8_t LENGTH = 10;uint8_t data[LENGTH];uint8_t crc;for(int i = 0; i < LENGTH; i++){data[i] = i*5;printf("%02x ", data[i]);}printf("\n");crc = crc8_maxim(data, LENGTH);printf("CRC-8/MAXIM:%02x\n", crc);return 0;
}

计算结果:

CRC 库代码分析

库中crc函数基本相似,一通百通。

/******************************************************************************* Name:    CRC-7/MMC           x7+x3+1* Poly:    0x09* Init:    0x00* Refin:   False* Refout:  False* Xorout:  0x00* Use:     MultiMediaCard,SD,ect.*****************************************************************************/
uint8_t crc7_mmc(uint8_t *data, uint16_t length)
{uint8_t i;// 这里的初值为 Init = 0x00uint8_t crc = 0;        // Initial valuewhile(length--){// 第一次进来,crc = 0,异或上任意值,crc = 任意值// 后续数据进行异或,因为前一次数据的后7位补0,相当于异或上这些0,就是把数据加到上次的数据末尾// 最后一个数据加在末尾后,在下面的for循环,把后面的7个零补回来了。crc ^= *data++;        // crc ^= *data; data++;for ( i = 0; i < 8; i++ ){// 判断这个高位是否是 1,最高位为 1 时才可异或上多项式if ( crc & 0x80 )// 因为最高位为一,异或上注定为0,直接省去计算crc = (crc << 1) ^ 0x12;        // 0x12 = 0x09<<(8-7)elsecrc <<= 1;}}// 因为是 7位宽的,而在循环中多向左移动了一位,再移动回来即可。return crc >> 1;
}

CRC 计算工具

下面这几款工具都可以自定义CRC算法模型,而且都有标准CRC模型可供选择。如果自己用C语言或者Verilog实现校验算法时,非常适合作为标准答案进行验证。

  • 在线计算:http://www.ip33.com/crc.html
  • 离线计算工具:CRC_Calc v0.1.exe或者GCRC.exe

格西CRC计算器:

总结

CRC校验并不能100%的检查出数据的错误,非常低的概率会出现CRC校验正确但数据中有错误位的情况。这和CRC的位数,多项式的选择等等有很大的关系,所以在实际使用中尽量选择标准CRC参数模型,这些多项式参数都是经过理论计算得出的,可以提高CRC的检错能力。CRC校验可以检错,也可以纠正单一比特的错误,你知道纠错的原理吗?

对于 CRC 校验的 学习笔记相关推荐

  1. CRC校验码学习笔记

    一.CRC校验的作用 CRC:循环冗余校验码,是数据通信领域中最常用的一种查错校验码,它的优点是信息字段和校验字段的长度可以任意选定.使用CRC的方法是,在数据传输前计算信息字段的CRC,将其作为校验 ...

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

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

  3. SpringMVC校验---SpringMVC学习笔记(八)

    校验的理解 项目中,通常使用较多是前端的校验,比如页面中js校验.对于安全要求较高点建议在服务端进行校验. 服务端校验: 控制层conroller:校验页面请求的参数的合法性.在服务端控制层conro ...

  4. Struts2 校验框架学习笔记

    2019独角兽企业重金招聘Python工程师标准>>> truts2 校验框架 Struts2 和Struts1同样也提供了校验框架,但在Struts2 已经不再把校验框架做为一个插 ...

  5. 【个人学习总结】CRC校验原理及实现

    [个人学习总结]CRC校验原理及实现 一.CRC校验原理[理论篇] 1.硬核视频讲解[重点看,非常非常好!!!] 2.基础文章[略看] 3.深入文章!!![代码.查表法有点看不懂,跨越有点大] 理解重 ...

  6. SpringMVC学习笔记

    文章目录 SpringMVC学习笔记 Spring MVC 什么是 MVC 设计模式? Spring MVC 的核心组件 Spring MVC 的工作流程 如何使用? Spring MVC 注解 Sp ...

  7. STM32CubeMX学习笔记(22)——CRC接口使用

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

  8. 学习笔记——CRC的基本原理与实现

    文章目录 笔记前言 一.CRC是什么? 二.CRC基本原理 1.原理介绍与练习 2.CRC-8 示例代码 总结 笔记前言 此篇是学习CRC基本原理与实现的个人学习笔记,以备未来自己复习使用,也将自己学 ...

  9. SilverLight学习笔记--实际应用(一)(4):手把手建立一个Silverlight应用程序之同步数据校验1...

    现在我们的程序有了添加和删除以及修改功能,下面我们看一看如何让程序具备数据校验功能.我们将用两种方式实现数据的校验,一种是在客户端进行同步校验.另一种是在服务器端进行异步校验.   本篇我们先实现如何 ...

最新文章

  1. android gradle错误,更新到Android Studio 2.3后出现Gradle错误
  2. MnasNet:迈向移动端机器学习模型设计的自动化之路
  3. Windows服务程序时钟调用
  4. Java Date Nuances的痛苦提醒
  5. mysql命令导出数据库_MYSQL 数据库导入导出命令
  6. 删除网络信息服务器端,网络安全:手动清除gh0st远控服务端
  7. 服务器安装固态硬盘的步骤,服务器系统安装中不识别固态硬盘问题
  8. awgn matlab,Matlab实现加性高斯白噪声信道(AWGN)下的digital调制格式识别分类
  9. linux 快照工具,技术预览:CentOS 7中利用Snapper GUI管理系统快照
  10. Apollo星火计划学习笔记——Apollo速度规划算法原理与实践
  11. AI 作画:Stable Diffusion 模型原理与实践
  12. server can;t find yao.com:SERVFAIL的原因
  13. CPU中的八个通用寄存器
  14. 用Python量化海龟交易法则
  15. 规则引擎Drools使用 第十二篇 Drools 的高级语法之RHS加强
  16. Odoo | Config | Odoo版本基础需求
  17. 酷我车载版显示服务器错误,酷我云盘服务器异常
  18. Kernels(similarity)核函数
  19. 攻防世界[刷题笔记]之Web方向(练习区)(后半)
  20. javascript_抛物线系列_04已知起点和终点画抛物线

热门文章

  1. android点击弹框,Android——js交互实现点击弹框
  2. 迈向高手殿堂——红警2坦克战全攻略
  3. 2022年度打印机行业数据报告:十大热门品牌销量排行榜
  4. w ndows平板电脑,微软推小尺寸平板是自废武功,完善体验才是出路
  5. 戴尔电脑无法自动修复此计算机,戴尔win10无限自动修复重置电脑时出现问题 你做对了吗?...
  6. 英文期刊催稿信模板_英文投稿的,询问进展,催稿 模版信
  7. [附源码]计算机毕业设计Python甜品购物网站(程序+源码+LW文档)
  8. 关于KINECT V2.0 C++ SDK 基础教程的笔记 EP2
  9. EP2 加载后的类存在的期限
  10. 设计一个70W在线人数的弹幕系统