CRC检错技术原理
一、题外话
说来惭愧,一开始是考虑写关于CRC检错技术更深层次数学原理的,然而在翻看《Basic Algebra》后,我果断放弃了这种不切实际的想法。个人觉得不是因为本人数学水平差或者能力差,而是研究生教材知识概念具有一定的连贯性,需要花大量时间研读。不过呢,我还是找到一本适合了解CRC技术的著作《纠错码的代数理论》---冯克勤,对数学感兴趣的朋友也可以在业余时间品读一下全书。
用国内搜索引擎搜索关于CRC检错技术的文章或者博客,内容也基本都是千篇一律,基本都是介绍如何模2运算。写下这篇文章,希望能够弥补一下国内所谓技术文章的部分不足之处。当然,最主要的还是帮助自己和读者有所提高。
二、循环冗余检错来源
CRC这个缩略词,在我看来可以有两种理解:一种是Cyclic Redundancy Check,即循环冗余检错技术;另一种则是Cyclic Redundance Code,即循环冗余校检码。在计算机网络中,基本上都是使用前一种,但是我也是见过能够理解成后者的说法的。
我第一次接触到CRC这个词是在计算机网络教材讲数据链路层帧的差错检测部分。实际的网络通信链路并非是理想的,即在网络通信中自身的电磁信号由于会受到外界电磁波或脉冲干扰的影响,会在比特传输过程中出现比特差错(属于传输差错的一种),因此为了保证计算机网络数据传输的可靠性,在网路传输数据时,必须采用差错检测措施。
在计算机网络发展过程中,数学起到了至关重要的作用。正当通信专家对差错检测措施一筹莫展的时候,团队中的数学家将抽象代数中的二元素伽罗瓦域(GF(2))引入,告诉我们可以通过数学手段解决数据的比特差错检测问题。其余的情况只能靠你们脑补了。
三、循环冗余检错原理
《计算机网络 第五版》---谢希仁所著的教材通过例子对循环冗余检验原理的原理说明如下:
在发送端,先把数据划分为组,假定每组k个比特。现假定待传送的数据M=101001(k=6)。CRC运算就是在数据M的后面添加供差错检测用的n位冗余码,然后构成一个帧发送出去,一共发送(k+n)位。在所要发送的数据后面增加n位的冗余码,虽然增大了数据传输的开销,但却可以进行差错检测。当传输可能出现错误时,付出这种代价往往是很值得的。
这n位冗余码可用以下方法得出。用二进制的模2运算进行
乘M的运算,这相当于在M后面添加n个0。得到的(k+n)位的数除以收发双方事先商定的长度为(n+1)位除数P,得出的商是Q而余数是R(n位,比P少一位)。关于除数P下面还要介绍。在图1所示的例子中,M=101001(即k=6)。假定除数P=1103(即n=3)。经模2除法运算后的结果是:商Q=110101(这个商并没有什么用处),而余数R=001。这个余数R就作为冗余码拼接在数据M的后面发送出去。这种为了进行检错而添加的冗余码常称为帧检验序列FCS(Frame Check Sequence)。因此加上FCS后发送的帧是101001001(即
),共有(k+n)位。

图1 循环冗余检测原理例子
顺便说一下,循环冗余检验CRC和帧检验序列FCS并不是同一概念。CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可以不选用CRC。
在接受端把接收到的数据以帧为单位进行CRC检验:把收到的每一个帧都除以同样的除数P(模2运算),然后检查得到的余数R。
如果在传输过程中无差错,那么经过CRC检验后得出的余数R肯定是0。但如果出现误码,那么余数R仍等于零的概率是非常非常小的(可以通过不太复杂的概率计算得出)。
总之,在接收端对收到的每一帧经过CRC检验后,有以下两种情况:
1)若得出的余数R=0,则判定这个帧没有差错,即接受(accept);
2)若余数R!=0,则判定这个帧有差错,即丢弃(discard)。
一种较方便的方法时用多项式来表示循环冗余检验过程。在上面的例子中,用多项式
表示上面的除数P=1101(最高位对应于
,最低位对应于
)。多项式P(X)称为生成多项式。现在广泛使用的生成多项式P(X)有以下几种:

在数据链路层,发送端帧检验序列FCS的生成和接收端的CRC检验都是用硬件完成的,处理很迅速,因此并不会延误数据的传输。
小结:
小结一下上述教材内容所提到的内容:

-----------------------------------------------------------------------------------上 帝 的 分 界 线------------------------------------------------------------------------------
这部分谈论的是CRC检错技术基于的数学原理,参考文章是GF(2)---wikipedia。
GF(2) (also F2, Z/2Z or Z2) is the Galois field of two elements. It is the smallest finite field.
wikipedia给出的定义如下:GF(2)是二元素伽罗瓦域,也是最小的有限域。

"模2运算"类比二进制运算的差别---无进、退位是由GF(2)性质决定的。

小结:
模2运算是特殊的四则运算,分为加模2运算、减模2运算、乘模2运算、除模2运算。
四、循环冗余检错实战

首先分析生成多项式
,显然n=3,因此循环冗余码应为3位二进制数。生成多项式代表的二进制除数P=1001,发送的数据为101110,则真实的被除数为101110000。进行减模2运算(异或运算)如下:

图4 模2运算步骤
于是得到FCS为011,因此发送数据实际为101110011(除以1001余数为0,读者可自行尝试)。注意到,在运算的时候,每次都会往后退一位,即第一位每次都是被消掉的。
五、曾经的困惑暨反思
当我一开始接触计算网络中CRC检测技术的时候,由于经验以及知识的匮乏,一直有一个问题困扰着我:如果网卡在发送帧时自动添加FCS到帧尾,那么接收端是如何判断的呢?接收端又不知道发送端用的除数P是多少。
现在回想起来,其实这种质问的想法似乎还挺有道理的。对于这个问题,其实这篇文章当中已经给出了问题的答案:计算机网络通信中,我们对生成多项式(除数)作了统一的标准,即针对不同的帧,发送端网卡添加不同的FCS,而接受端网卡知道相应帧该用CRC-16还是CRC-32来检错。
问题解决了,接着简单谈谈在学习CRC检错技术后的有啥收获吧。说实在的,之前只知道线性代数、数论等在计算机算法领域有着广泛的应用,没有想到计算机领域还用到了群论这门高深的学问。莎士比亚有句名言:"聪明的人总认为自己是笨蛋,而笨蛋却总以为自己很聪明"。再接再励,在工作中坚持学习吧。
CRC检错技术原理的更多相关文章
- CRC的校验原理
一.基本原理 CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n=p+r位的二进制序列:附加在数据序列之后的这个检验码与数据序列的内容之间存在着 ...
- Atitit.ide技术原理与实践attilax总结
Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...
- Atitit.异步编程技术原理与实践attilax总结
Atitit.异步编程技术原理与实践attilax总结 1. 俩种实现模式 类库方式,以及语言方式,java futuretask ,c# await1 2. 事件(中断)机制1 3. Await 模 ...
- Atitit 语音识别的技术原理
Atitit 语音识别的技术原理 1.1. 语音识别技术,也被称为自动语音识别Automatic Speech Recognition,(ASR),2 1.2. 模型目前,主流的大词汇量语音识别系统多 ...
- Atitit.gui api自动化调用技术原理与实践
Atitit.gui api自动化调用技术原理与实践 gui接口实现分类(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Sol ...
- 新手入门:史上最全Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- <转>VPN技术原理
原文地址:VPN技术原理 VPN,Virtual Private Network(虚拟专用 网络),被定义为通过一个公用网络(通常是因特网)建立一个临时的.安全的连接,是一条穿过公用网络的安全.稳定的 ...
- seo伪原创技术原理分析,php实现伪原创示例
seo伪原创技术原理分析,php实现伪原创示例 现在seo伪原创一般采用分词引擎以及动态同义词库,模拟百度(baidu),谷歌(google)等中文切词进行伪原创,生成后的伪原创文章更准确更贴近百度和 ...
随机推荐
- 解决Visual Code安装中文插件失败问题
早已听闻Visual Code的大名,今日一用,果然不同凡响. 只不过,我的常用开发环境是不联网的,需要离线安装Visual Code和扩展插件. 以前要安装插件只能从VsCode里装,想离线安装比较 ...
- 【旧文章搬运】VC插件中如何获取当前工程的工作目录
原文发表于百度空间,2014-09-24========================================================================== 好难找的资 ...
- #if _MSC_VER > 1000 #pragma once #endif
#if _MSC_VER > 1000 #pragma once #endif 解释: 这是微软的预编译控制. 在_MSC_VER较小时,它对一些东西的支持与新版不同 _MSC_VER分解如下: ...
- oracle练习题 实验一
实验一 练习1.请查询表DEPT中所有部门的情况. select * from dept; 练习2.查询表DEPT中的部门号.部门名称两个字段的所有信息. select deptno,dname fr ...
- [poj1222]EXTENDED LIGHTS OUT(高斯消元)
题意:每个灯开启会使自身和周围的灯反转,要使全图的灯灭掉,判断灯开的位置. 解题关键:二进制高斯消元模板题. 复杂度:$O({n^3})$ #include<cstdio> #includ ...
- fastreport整理
Q1:如何直接打印,不显示打印对话框? frxReport1.PrintOptions.ShowDialog := false; frxReport1.PrepareReport(true); frx ...
- Power OFF and ON USB device in linux (ubuntu)
Power OFF and ON USB device in linux (ubuntu) http://loginroot.com/power-off-and-on-usb-device-in-li ...
- Jinkins定时任务设置
设置的地方在构建触发器中 Build after other projects are built:在其他项目构建完成后再进行构建. Build periodically:周期进行构建 Build w ...
- Python之将Python字符串生成PDF
笔者在今天的工作中,遇到了一个需求,那就是如何将Python字符串生成PDF.比如,需要把Python字符串'这是测试文件'生成为PDF, 该PDF中含有文字'这是测试文件'. 经过一番检索, ...
- Spark history server 遇到的一些问题
最近学习Spark,看了一个视频,里面有提到启动spark后,一般都会启动Spark History Server.视频里把 spark.history.fs.logDirectory 设置成了Had ...