我们知道在以太网帧的末尾有一个叫FCS的东西。
全称:Frame Check Sequence,中文名:帧检验序列
这个东西是用来检验我们的数据是否在传输的过程中被破坏(不一定是收到攻击,也可能是一些物理干扰),以更好的安排重发。
而其中最常用的,也是检错能力很强的,就是CRC,循环冗余校验码。

操作流程

一个小背景知识

模二除法,或者说在数域{1,0}上的除法。
与普通除法类似,它也可以列竖式计算,但是唯一不同的,是相减的那一步。
我们这里的除法,在相减时,遵循一下规则:

  1. 1-1=0
  2. 1-0=1
  3. 0-1=1
  4. 0-0=0
  5. 不进位,也不借位

举个例子。

我相信应该很清楚了。(手画的,不容易)

生成

首先,我们需要一个除数,这个除数可以按照某个行业标准来,比如:

IBM的SDLC(同步数据链路控制)规程中使用的CRC-16为:11000000000000101,在ISO HDLC(高级数据链路控制)规程、ITU的SDLC、X.25、V.34、V.41、V.42等中使用CCITT-16为:11000000000100001。

当然这里做个实验,我们也可以随机生成,但是有一点要求,最高位和最低为必须为1,这一点需要注意。

接下来,我们把数据左移(k-1)位,补零,这就是我们的被除数。
然后用这个被除数和除数做模二除法得到余数。
这个余数(k-1位,不足的话,左侧补零),就是加在数据末尾的FCS。
然后我们把它加在数据末尾即可。

校验

那么我们如何校验呢?
直接把我们得到的串(包含FCS),对除数再做一次模二除法,如果余数是零,则说明数据完好。如果不为0,则说明数据遭到破坏,需要安排重发。

代码实现

相信看了上面的内容,应该很容易实现代码,下面给出我写的代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
using namespace std;
struct bin{//二进制数据 int num[100000];int len;void init(){//初始化为0 len=1;memset(num,0,sizeof(num));}void read(){//读入数字 char c[100000];scanf("%s",c);len=strlen(c);for(int i=0;i<len;i++){num[i]=c[len-i-1]-'0';}}void clean(){//清除前导0 for(int i=99999;i>=0;i--){if(num[i]==1){len=i+1;return;}}len=1;}void gen(int k){//随机生成 len=k;num[len-1]=num[0]=1;for(int i=1;i<len-1;i++){num[i]=rand()%2;}}bin operator =(bin b){//赋值符号 len=b.len;for(int i=0;i<len;i++){num[i]=b.num[i];}return *this;}bin operator +(bin b){//加法 bin c;c.init();c.len=max(b.len,len);for(int i=0;i<c.len;i++){c.num[i]=num[i]+b.num[i];}return c;}bin operator <<=(int b){//左移 for(int i=len-1;i>=0;i--){num[i+b]=num[i];num[i]=0;}len+=b;return *this;}bin operator /(bin b){//除法取余数(返回值为余数) bin c;c.init();c=*this;for(int i=c.len-1;i>=0&&i>=(b.len-1);i--){if(!c.num[i]){continue;}for(int j=i;j>i-b.len;j--){c.num[j]-=b.num[j-i+b.len-1];if(c.num[j]<0){c.num[j]=1;}}}c.clean();return c;}int operator ==(bin b){//等于号 if(b.len!=len){return 0;}for(int i=0;i<len;i++){if(num[i]!=b.num[i]){return 0;}}return 1;}void print(){//打印 for(int i=len-1;i>=0;i--){printf("%d",num[i]);}printf("\n");}
};
int main(){//设定k值 int k=5;srand(time(0));//定义各种量 bin text,key,div,txt,zero;//初始化 div.init();key.init();txt.init();zero.init();text.init();//生成 text.read();//读入数据 key.gen(5);//生成除数 txt=text; txt<<=(k-1);//数据左移 div=txt/key;//取余数 (FCS) txt=txt+div;// 合成 //模拟破坏
//  txt.num[txt.len/2]^=1;//校验txt=txt/key;if(txt==zero){printf("The data are OK!");} else{printf("The data are fault!");}return 0;
}

还可以完善的,我就不进一步完善了。

一些数学原理

之前有说数学背景,但是那只是为了能理解其过程,但并不能让我们明白为什么是这样。
所以这里扩展了一块内容,根据兴趣阅读一下吧!

生成多项式

不知道怎么说,就举例说明吧。


其对应的除数分别为:

  1. 11000000000000101
  2. 10001000000100001
  3. 100000100110000010001110110110111

我相信你应该明白了。

为什么余数为0

我们刚刚介绍了模二除法。
这里我们再说一个模二加法。

  1. 1+1=0
  2. 1+0=1
  3. 0+0=0
  4. 不进位

为什么是这样定义?
因为模二。
所以你只要让结果对2取模,你就知道为什么会这样了。
我们设原数据左移后为t,除数为a,商为s,余数为r。
所以有:t=as+r
而我们传递的是t+r
即t+r=a
s+r+r
有什么问题?
我们看一下r+r
注意这里是模二加法,不进位,且1+1=0+0=0,
而r和r是一样的,所以模二相加后,就是0!
所以式子变为:t+r=a*s
这样的话(t+r)模二除以a,自然余数为0。
这就是为什么我们可以这么做。

校验成功一定没错吗?

不一定!
有可能会出现某几位错了,但是判断结果是对的。
那么概率是多少呢?
假设FCS为32位(4字节)
数据我们取为8000位(1000字节,此处数据大小取了一个中值,以太网帧中的数据通常为46~1500字节)(当然了,其实从后面的结果可以知道此处并无影响)
8000位数据,最大为8000个1,最小为1(7999个0)。
进行二进制除法,商最大为7969位,总共有27969个可能的商。
总共可能破坏的结果为28000.
所以误判的概率为P=(27969-1)/28000
也就约为1/231,即1/2,147,483,648
这概率是多大呢?
差不多是生一个六胞胎的概率吧。
想一想,你身边有几个六胞胎?你听过几个六胞胎?
因此,其检错能力是很强的。重点是算法也很简单,方便实际应用。

结束语

这就是今天对CRC的探究,喜欢的话点一个赞呗!
有什么问题也欢迎与我讨论!

CRC码计算及原理(FCS帧校验序列生成)相关推荐

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

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

  2. CRC校验码计算,以常用CRC-8为例

    CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定. CRC校验原理:在要发送的帧后面附加一个数,生成一个新帧发送给接收端.它要使所生成的新帧 ...

  3. C语言CRC校验码计算与校验

    循环冗余校验(cyclicredundancy check,CRC)对传输序列进行一次规定的除法操作,将除法操作的余数附加在传输信息的后面.在接收端,也对收到的数据做相同的除法.如果接收端除法得到的结 ...

  4. bcc校验码计算_CRC校验你会吗?计算、校验、C语言实现,三步教你轻松搞定

    目录 前言 CRC算法简介 CRC计算 CRC校验 CRC计算的C语言实现 CRC计算工具 总结 前言 最近的工作中,要实现对通信数据的CRC计算,所以花了两天的时间好好研究了一下,周末有时间整理了一 ...

  5. java 文件crc校验_JavaCRC校验原理

    一.基本原理 CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n=p+r位的二进制序列:附加在数据序列之后的这个检验码与数据序列的内容之间存在着 ...

  6. bcc校验位怎么算的_数据BCC校验码计算工具

    这是数据BCC校验码计算工具下载,获得数据BCC校验码工具,MFC开发,使用方便,输入数据16进制字符串,点击计算生成BCC码.. 软件介绍 数据BCC校验码计算工具,难免会发生错误.为了避免这种错误 ...

  7. 一文搞定校验码(奇偶校验,海明,CRC 码)

    文章目录 效验码 计算码距方法 奇偶校验码 校验原理 奇偶校验 异或法制 总结 海明校验码 海明校验码的分布规律 海明码纠错以及定位 实现原理 海明码完善 总结 循环冗余校验码(CRC) 模2除算法 ...

  8. 2.1.5 校验码(一文带你分析搞懂:奇偶校验码、海明码、CRC码)

    文章目录: 什么是校验码? 为什么要有校验码? 1.奇偶校验码 怎么通过奇偶校验码判断数据是正确还是错误呢? (1)奇校验 (2)偶校验 为什么无法检查出偶数个错误? 2.海明(汉明)校验码 什么是海 ...

  9. java 偶校验_一文搞定校验码(奇偶校验,海明,CRC 码)

    效验码 校验码:指能够发现或能够自动纠正错误的数据编码,也称检错纠错编码. 实现原理:通过加一冗余码,来检验或纠错编码 码字 : 由若干位代码组成的一个字 码距:将两个码字逐位进行对比,具有不同的位的 ...

最新文章

  1. 如何利用装饰者模式在不改变原有对象的基础上扩展功能
  2. Spring Boot 2应用程序和OAuth 2 –传统方法
  3. 前端学习(1959)vue之电商管理系统电商系统之通过路由加载分类参数
  4. ios开发网络篇—HTTP协议 - 转
  5. ADO.NET Entity Framework 学习
  6. Web系统开发构架再思考-前后端的完全分离 MVVM
  7. 《Region Proposal by Guided Anchoring》阅读笔记
  8. 美国弗吉尼亚大学计算机科学,弗吉尼亚大学计算机科学专业
  9. 修改/忘记数据库密码
  10. 【Servlet】什么情况下调用doGet和doPost
  11. uni-app 微信小程序获取位置信息提示“getLocation 需要在 app.json 中申明 permission 字段”
  12. 关于群晖 transmission安装及汉化
  13. python中矩阵的表示方法,稀疏矩阵在Python中的表示方法
  14. 微极速彩虹易支付第四方免签支付平台源码
  15. 宝宝生活点滴(2009.11)
  16. signature=9584e09619c4aa010122e7ad7d4cb4c6,来用百度密语吧!!!
  17. 2020 Maven无法使用阿里云仓库下载的解决方法
  18. 计算机专业英语教程第五版课文,计算机专业英语教程阅读
  19. 大学毕业的农村孩子!
  20. 大数据项目(一)————生成团购标签

热门文章

  1. Python生成个性二维码详解!
  2. 计算机毕设(附源码)JAVA-SSM基于java的高校学生实习管理系统设计
  3. cs224w(图机器学习)2021冬季课程学习笔记5 Colab 1:Node Embeddings
  4. php如何导出带动画的ppt,ppt如何导出gif动画 我要ppt可以转视频,或者gif动画
  5. 漫画算法-学习笔记(11)
  6. 【带你刷华为机试】——字符串分割
  7. 【unity】建一个传送门
  8. A. Serval and Mocha‘s Array codeforces 1789A
  9. 你真的懂面形误差PV和RMS的计算方法吗?均方根(RMS)与方差、标准差有什么区别?Zemax中的波前RMS是什么?(光学测量、光学设计必看)
  10. 【UE4】将pmx导入到ue4中(obj-zip-mixamo绑骨)|模之屋模型导入UE4(较详细)