CRC校验算法详解及代码实现

一、 CRC校验算法前置知识

在学习CRC校验算法之前,先复习一下CRC会涉及的主要几个主要的算法。

1. 异或

异或,就是不同为1,相同为0,运算符号是^。
0^0 = 0
0^1 = 1
1^1 = 0
1^0 = 1

异或运算存在如下几个规律,需要了解。

  1. 0^x = x 即0 异或任何数等于任何数
  2. 1^x = ~x 即1异或任何数等于任何数取反
  3. x^x = 0 即任何数与自己异或,结果为0
  4. a ^ b = b ^ a 交换律
  5. a ^ (b ^ c) = (a ^ b) ^c 结合律

2. 模2加法

模2加法相对于普通的算术加法,主要的区别在模2加法,不做进位处理。具体结果如下。
0+0 = 0
0+1 = 1
1+1 = 0
1+0 = 1
我们发现模2加法的计算结果,同异或运算结果一模一样。进一步推演,我们会发现,异或运算的5个规律,同样适合于模2加法。这里,就不在一一列举了。

3. 模2减法

模2减法相对于普通的算术减法,主要的区别在模2减法,不做借位处理。具体结果如下。
0-0 = 0
0-1 = 1
1-1 = 0
1-0 = 1
我们发现模2减法的计算结果,同模2加法,以及异或的运算结果一模一样。进一步推演,我们会发现,异或运算的5个规律,同样适合于模2减法。这里,就不在一一列举了。

4. 模2除法

模2除法相对于普通的算术除法,主要的区别在模2除法,它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。下面是一个模2除法的示例。被除数是101001000,除数1101。

选取被除数前面的1010模2除以除数1101,因最高为是1,所以,得到商1,余数通过1010和1101的模2减法获得,根据前面的模2减法运算的介绍,其运算结果和异或运算一模一样。因此,得到余数:1010 ^ 1101 = 0111。去掉最高位的0,得到111,再将上面被除数的下一位,即0拿下来,得到1110。1110模2除以1101,得到商1,余数1110 ^ 1101 = 0011。除掉最高为的0,拿下被除数的下一位,即1,得到0111。此时,因为最高位是0,所以得到商0,余数0111 ^ 0000 = 0111。去掉最高为的,再和被除数的下一位结合,继续模2除法。按照上图依次计算,可以得到最终的商110101,余数001。
从上面的示例,我们看到一个规律:每循环一次模2计算,如果得到的被除数最高位是0,则一轮循环使用0000作为除数。如果得到的被除数最高位是1,则下一轮循环除数使用1101。这样可以保证每一轮循环被除数都能向右平移一位,直到循环到被除数最后一位。
根据之前章节中介绍的异或运算的几条规律,我们可以很容易得到一个结论,如果我们将模2除法的余数和被除数的最后几位(与余数的位数一下,本例中就是3)异或之后,得到一个新的数,这个新的数,再使用模2除法除以除数1101,即可整除,即余数为0。

二、 CRC校验算法及实现

CRC校验的根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数值整除(注意,这里不是直接采用二进制除法,而是采用 “模2除法”)。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。

具体来说,CRC校验原理就是以下几个步骤:

  1. 先选择(可以随机选择,也可按标准选择,具体在后面介绍)一个用于在接收端进行校验时,对接收的帧进行“模2除法”运算的除数(是二进制比较特串,通常是以多项方式表示,所以CRC又称多项式编码方法,这个多项式也称之为“生成多项式”)。
  2. 看所选定的除数二进制位数(假设为k位),然后在要发送的数据帧(假设为m位)后面加上k-1位“0”,然后以这个加了k-1个“0“的新帧(一共是m+k-1位)以“模2除法”方式除以上面这个除数,所得到的余数(也是二进制的比特串)就是该帧的CRC校验码,也称之为FCS(帧校验序列)。但要注意的是,余数的位数一定要是比除数位数只能少一位,哪怕前面位是0,甚至是全为0(附带好整除时)也都不能省略。
  3. 再把这个校验码附加在原数据帧(就是m位的帧,注意不是在后面形成的m+k-1位的帧)后面,构建一个新帧发送到接收端,最后在接收端再把这个新帧以“模2除法”方式除以前面选择的除数,如果没有余数,则表明该帧在传输过程中没出错,否则出现了差错。

从上面可以看出,CRC校验中有两个关键点:
一是要预先确定一个发送端和接收端都用来作为除数的二进制比特串(或多项式);
二是把原始帧并追加k-1位"0"后得到的新帧与上面选定的除数进行模2除法运算,计算出CRC。
前者可以随机选择,也可按国际上通行的标准选择,但最高位和最低位必须均为“1”,如在IBM的SDLC(同步数据链路控制)规程中使用的CRC-16(也就是这个除数一共是17位,这样的话,得到的余数的位数就是17-1=16)生成多项式g(x)= x16 + x15 + x2 +1(对应二进制比特串为:11000000000000101)。

理论上,使用上述CRC校验步骤的第二步计算CRC的时候,需要将所有的二进制序列(包括后加的k-1个0)作为一个整体按照第一章节中模2除法的方法,除以选定的除数。但是,考虑模2除法中实际使用的运算其实一直都是按位异或,结合异或运算的结合律,我们逐个bit逐个bit地将作为被除数的二进制序列的每个bit依次引入,也可以逐个字节逐个字节的引入。下面是通过逐个字节引入方式计算CRC的代码实现,假设校准使用的多项式为x8+x5+x4+1 (对应二进制为: 0b100110001,对应HEX值为0x131)。

/***************************************
*@DESCRIPTION: -- CRC8计算,
*
*@Parameters: -- *data_ptr:待计算CRC8的数据
*                len:待计算CRC8数据的长度
*
*@Return: --无
****************************************/
unsigned char calculate_crc8(unsigned char *data_ptr, unsigned char len)
{unsigned int i;unsigned char j;unsigned char crc = 0x00;for (i=0; i<len; i++){crc ^= *data_ptr;data_ptr++;for (j=8; j>0; j--){if (crc & 0x80){crc <<= 1;crc ^= 0x31;    // 0x131最高位1去掉,只与低8bit的0x31异或即可。} // if (crc & 0x80)else{ crc <<= 1;/*当最高bit为0时,则crc与0按位异或,仍为crc,所以,没有语句"crc ^= 0x31;”。*/} // else} // for (j=8; j>0; j--)} // for (i=0; i<len; i++)return crc;
}

CRC校验算法详解及代码实现相关推荐

  1. 粒子群(pso)算法详解matlab代码,粒子群(pso)算法详解matlab代码

    粒子群(pso)算法详解matlab代码 (1)---- 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,C ...

  2. 数学建模——主成分分析算法详解Python代码

    数学建模--主成分分析算法详解Python代码 import matplotlib.pyplot as plt #加载matplotlib用于数据的可视化 from sklearn.decomposi ...

  3. Go-AES算法详解与代码

    目录 AES 发展史 概述 轮函数F 字节代换 行移位 列混淆 轮密钥加 密钥编排 AES和DES的不同之处 分组模式CTR AES的Go实现 aes包 cipher包 加密/解密 参考 本篇介绍分组 ...

  4. 【分享实录】BANCOR算法详解及代码实现

    1 活动基本信息 1)主题:[区块链技术工坊22期]BANCOR算法详解及代码实现 2)议题: BANCOR算法的特点和优劣势 BANCOR算法和举例 如何加入BANCOR.NETWORK交易所 如何 ...

  5. 技术工坊|BANCOR算法详解及代码实现(上海)

    2019独角兽企业重金招聘Python工程师标准>>> EOS项目在RAM分配中采用了Bancor算法,并将RAM的价格爆炒到了很高的价位,凭借EOS项目在区块链领域的强大运营宣传能 ...

  6. 【区块链技术工坊22期实录】王登辉:BANCOR算法详解及代码实现

    1,活动基本信息 1)题目: [区块链技术工坊22期]BANCOR算法详解及代码实现 2)议题: 1)BANCOR算法的特点和优劣势 2)BANCOR算法和举例 3)如何加入BANCOR.NETWOR ...

  7. 算法 经典的八大排序算法详解和代码实现

    算法 经典的八大排序算法详解和代码实现 排序算法的介绍 排序的分类 算法的时间复杂度 时间频度 示例 图表理解时间复杂度的特点 时间复杂度 常见的时间复杂度 空间复杂度 排序算法的时间复杂度 冒泡排序 ...

  8. [联邦学习] FedAvg聚合算法详解及代码实现

    该文章首发于若绾 [联邦学习] FedAvg聚合算法详解及代码实现,转载请标注出处. 论文原文:Communication-Efficient Learning of Deep Networks fr ...

  9. KMP算法详解及代码

    KMP算法详解及代码 KMP算法详解及代码 定义及应用 理论 基本概念 next 数组 总结 注意 代码 KMP算法详解及代码 最近正好在看字符串相关的算法内容,就顺便把KMP算法回顾了一下.相应的代 ...

  10. 谱聚类算法详解及代码实现

    谱聚类算法详解及代码实现 文章目录 谱聚类算法详解及代码实现 参考 关于谱聚类介绍 谱聚类概述 谱聚类前置知识 无向权重图 邻接矩阵 度矩阵 拉普拉斯矩阵 相似度矩阵 确定目标函数 初始化目标函数(最 ...

最新文章

  1. eclipse java代码颜色设置颜色设置颜色设置颜色设置颜色_eclipse设置(颜色,字体等)...
  2. linux用户态驱动--VIFIO、IOMMU、UIO(二)
  3. Splunk和ElasticSearch深度对比解析
  4. 大型网站的架构演进从一个电商网站开始
  5. iOS 提交app到iTunes Connect预览截图截取方法及尺寸大小
  6. android studio for android learning (二十四 )bitmap and bitmapFactory
  7. 如何用通俗易懂的语言解释需求变更带来的项目影响
  8. php moodle mysql_搭建基于Windows + Apache + PHP + MySQL的Moodle平台
  9. Java实现图片水印
  10. 加拿大计算机科学薪酬,加拿大最好找工作及薪酬最高的十大专业介绍
  11. 数字舵机与模拟舵机_控制方法与性能比较
  12. 常用工具方法(7S,28,SWOT,PDCA,SMART,6W2H,时间管理四矩阵,WBS,碎石分析,ORID)
  13. 流年似水 启航2019
  14. mezzanine安装(python2.7+nginx+mysql+supervisor)
  15. 七彩虹将星 X15 AT 2023 参数配置 七彩虹将星 X15 AT 评测
  16. tcpreplay命令详解
  17. 中英互译软件工程设计
  18. [转载]读史札记22:政治家的道德底线——谈李斯之死
  19. 鞋之语告诉你如何开好一个新式洗鞋店
  20. 字符串匹配算法题:病毒感染监测

热门文章

  1. (开源)微信小程序实时控制stc89c51,通过esp8266
  2. PHP汉字转化为拼音
  3. pb11.5调用系统打印机
  4. unraid win10_搞定unraid直通核显给WIN10后黑屏、声卡无输出问题
  5. 真北方向、坐标北向以及磁北向
  6. 大数据项目实训教学解决方案
  7. Querydsl使用fetchCount()报错
  8. 【性能优化实战】日语java开发相关词汇
  9. kuangbin专题一——Fliptile
  10. 用C++编写银行叫号系统,项目开源,适合零基础小白学习!