计算机网络CRC检验中为啥选择16或32位效验码,效率最高?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络CRC检验中为啥选择16或32位效验码,效率最高?相关的知识,希望对你有一定的参考价值。

参考技术A 循环冗余校验(CRC)是一种根据网络数据封包或电脑档案等数据产生少数固定位数的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者储存之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。由于本函数易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。它是由W.WesleyPeterson在他1961年发表的论文中披露[1]。noteTA|T=zh-hans:循环冗余校验;zh-hant:循环冗余校验;|1=zh-hans:循环冗余校验;zh-hant:循环冗余校验;'''循环冗余校验'''(CRC)是一种根据网路数据封包或[[电脑档案]]等数据产生少数固定位数的一种[[散列函数]],主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者储存之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。由于本函数易于用二进制的[[电脑硬件]]使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。它是由[[W.WesleyPeterson]]在他1961年发表的论文中披露citejournal|author=Peterson,W.W.andBrown,D.T.|year=1961|month=January|title=CyclicCodesforErrorDetection|journal=ProceedingsoftheIRE|doi=10.1109/JRPROC.1961.287814|issn=0096-8390|volume=49|pages=228。==简介==CRC“校验和”是两个位元数据流采用二进制除法(没有进位,使用XOR异或来代替减法)相除所得到的余数。其中被除数是需要计算校验和的信息数据流的二进制表示;除数是一个长度为n+1的预定义(短)的二进制数,通常用多项式的系数来表示。在做除法之前,要在信息数据之后先加上n个0.CRCa是基于[[有限域]]GF(2)([[同余|关于2同余]])的[[多项式环]]。简单的来说,就是所有系数都为0或1(又叫做二进制)的多项式系数的集合,并且集合对于所有的代数操作都是封闭的。例如::(x^3+x)+(x+1)=x^3+2x+1\equivx^3+12会变成0,因为对系数的加法都会模2.乘法也是类似的::(x^2+x)(x+1)=x^3+2x^2+x\equivx^3+x我们同样可以对多项式作除法并且得到商和余数。例如,如果我们用''x''3+''x''2+''x''除以''x''+1。我们会得到::\frac(x^3+x^2+x)(x+1)=(x^2+1)-\frac1(x+1)也就是说,:(x^3+x^2+x)=(x^2+1)(x+1)-1这里除法得到了商''x''2+1和余数-1,因为是奇数所以最后一位是1。字符串中的每一位其实就对应了这样类型的多项式的系数。为了得到CRC,我们首先将其乘以x^n,这里n是一个固定多项式的[[多项式的阶|阶]]数,然后再将其除以这个固定的多项式,余数的系数就是CRC。在上面的等式中,x^2+x+1表示了本来的信息位是111,x+1是所谓的'''钥匙''',而余数1(也就是x^0)就是CRC.key的最高次为1,所以我们将原来的信息乘上x^1来得到x^3+x^2+x,也可视为原来的信息位补1个零成为1110。一般来说,其形式为::M(x)\cdotx^n=Q(x)\cdotK(x)+R(x)这里M(x)是原始的信息多项式。K(x)是n阶的“钥匙”多项式。M(x)\cdotx^n表示了将原始信息后面加上n个0。R(x)是余数多项式,既是CRC“校验和”。在通讯中,发送者在原始的信息数据M后加上n位的R(替换本来附加的0)再发送。接收者收到M和R后,检查M(x)\cdotx^n-R(x)是否能被K(x)整除。如果是,那么接收者认为该信息是正确的。值得注意的是M(x)\cdotx^n-R(x)就是发送者所想要发送的数据。这个串又叫做''codeword''.CRCs经常被叫做“[[校验和]]”,但是这样的说法严格来说并不是准确的,因为技术上来说,校验“和”是通过加法来计算的,而不是CRC这里的除法。“[[错误纠正编码]]”常常和CRCs紧密相关,其语序纠正在传输过程中所产生的错误。这些编码方式常常和数学原理紧密相关。==实现====变体==CRC有几种不同的变体*shiftRegister可以逆向使用,这样就需要检测最低位的值,每次向右移动一位。这就要求polynomial生成逆向的数据位结果。''实际上这是最常用的一个变体。''*可以先将数据最高位读到移位寄存器,也可以先读最低位。在通讯协议中,为了保留CRC的[[突发错误]]检测特性,通常按照[[物理层]]发送数据位的方式计算CRC。*为了检查CRC,需要在全部的码字上进行CRC计算,而不是仅仅计算消息的CRC并把它与CRC比较。如果结果是0,那么就通过这项检查。这是因为码字M(x)\cdotx^n-R(x)=Q(x)\cdotK(x)可以被K(x)整除。*移位寄存器可以初始化成1而不是0。同样,在用算法处理之前,消息的最初n个数据位要取反。这是因为未经修改的CRC无法区分只有起始0的个数不同的两条消息。而经过这样的取反过程,CRC就可以正确地分辨这些消息了。*CRC在附加到消息数据流的时候可以进行取反。这样,CRC的检查可以用直接的方法计算消息的CRC、取反、然后与消息数据流中的CRC比较这个过程来完成,也可以通过计算全部的消息来完成。在后一种方法中,正确消息的结果不再是0,而是\sum_i=n^2n-1x^i除以K(x)得到的结果。这个结果叫作核验多项式C(x),它的十六进制表示也叫作[[幻数]]。按照惯例,使用CRC-32多项式以及CRC-16-CCITT多项式时通常都要取反。CRC-32的核验多项式是C(x)=x^31+x^30+x^26+x^25+x^24+x^18+x^15+x^14+x^12+x^11+x^10+x^8+x^6+x^5+x^4+x^3+x+1。==错误检测能力==CRC的错误检测能力依赖于关键多项式的阶次以及所使用的特定关键多项式。''误码多项式''E(x)是接收到的消息码字与正确消息码字的''异或''结果。当且仅当误码多项式能够被CRC多项式整除的时候CRC算法无法检查到错误。*由于CRC的计算基于除法,任何多项式都无法检测出一组全为零的数据出现的错误或者前面丢失的零。但是,可以根据CRC的[[#变体|变体]]来解决这个问题。*所有只有一个数据位的错误都可以被至少有两个非零系数的任意多项式检测到。误码多项式是x^k,并且x^k只能被i\lek的多项式x^i整除。*CRC可以检测出所有间隔距离小于[[多项式阶次]]的双位错误,在这种情况下的误码多项式是E(x)=x^i+x^k=x^k\cdot(x^i-k+1),\;i>k。如上所述,x^k不能被CRC多项式整除,它得到一个x^i-k+1项。根据定义,满足多项式整除x^i-k+1的i-k最小值就是多项是的阶次。最高阶次的多项式是[[本原多项式]],带有二进制系数的n阶多项式==CRC多项式规范==下面的表格略去了“初始值”、“反射值”以及“最终异或值”。*对于一些复杂的校验和来说这些十六进制数值是很重要的,如CRC-32以及CRC-64。通常小于CRC-16的CRC不需要使用这些值。*通常可以通过改变这些值来得到各自不同的校验和,但是校验和算法机制并没有变化。CRC标准化问题*由于CRC-12有三种常用的形式,所以CRC-12的定义会有歧义*在应用的CRC-8的两种形式都有数学上的缺陷。*据称CRC-16与CRC-32至少有10种形式,但没有一种在数学上是最优的。*同样大小的CCITTCRC与ITUCRC不同,这个机构在不同时期定义了不同的校验和。==常用CRC(按照ITU-IEEE规范)==|class="wikitable"!名称||多项式||表示法:正常或者翻转|-|CRC-1||x+1(用途:硬件,也称为[[奇偶校验位]])||0x1or0x1(0x1)|-|CRC-5-CCITT||x^5+x^3+x+1([[ITU]]G.704标准)||0x15(0x??)|-|CRC-5-USB||x^5+x^2+1(用途:[[USB]]信令包)||0x05or0x14(0x9)|-|CRC-7||x^7+x^3+1(用途:通信系统)||0x09or0x48(0x11)|-|CRC-8-ATM||x^8+x^2+x+1(用途:ATMHEC)||0x07or0xE0(0xC1)|-|CRC-8-[[CCITT]]||x^8+x^7+x^3+x^2+1(用途:[[1-Wire]][[总线]])|||-|CRC-8-[[Dallas_Semiconductor|Dallas]]/[[Maxim_IC|Maxim]]||x^8+x^5+x^4+1(用途:[[1-Wire]][[bus]])||0x31or0x8C|-|CRC-8||x^8+x^7+x^6+x^4+x^2+1||0xEA(0x??)|-|CRC-10||x10+x9+x5+x4+x+1||0x233(0x????)|-|CRC-12||x^12+x^11+x^3+x^2+x+1(用途:通信系统)||0x80For0xF01(0xE03)|-|CRC-16-Fletcher||参见[[Fletcher'schecksum]]||用于[[Adler-32]]A&BCRC|-|CRC-16-CCITT||''x''16+''x''12+''x''5+1([[X25]],[[V.41]],[[Bluetooth]],[[PPP]],[[IrDA]])||0x1021or0x8408(0x0811)|-|CRC-16-[[IBM]]||''x''16+''x''15+''x''2+1||0x8005or0xA001(0x4003)|-|CRC-16-[[BBS]]||x16+x15+x10+x3(用途:[[XMODEM]]协议)||0x8408(0x????)|-|CRC-32-Adler||See[[Adler-32]]||参见[[Adler-32]]|-|CRC-32-MPEG2||See[[IEEE802.3]]||参见[[IEEE802.3]]|-|CRC-32-[[IEEE802.3]]||x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1||0x04C11DB7or0xEDB88320(0xDB710641)|-|CRC-32C(Castagnoli)||x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+1||0x1EDC6F41or0x82F63B78(0x05EC76F1)|-|CRC-64-ISO||x^64+x^4+x^3+x+1(use:ISO3309)||0x000000000000001Bor0xD800000000000000(0xB000000000000001)|-|CRC-64-[[EcmaInternational|ECMA]]-182||x^64+x^62+x^57+x^55+x^54+x^53+x^52+x^47+x^46+x^45+x^40+x^39+x^38+x^37+x^35+x^33+x^32+x^31+x^29+x^27+x^24+x^23+x^22+x^21+x^19+x^17+x^13+x^12+x^10+x^9+x^7+x^4+x+1(asdescribedin[CRC16toCRC64collisionresearch]*[index.htm#SAR-PR-2006-05ReversingCRC–TheoryandPractice.]math-stub[[Category:校验和算法]][[bg:CRC]][[ca:Controlderedundànciacíclica]][[cs:Cyklickýredundantnísoučet]][[de:ZyklischeRedundanzprüfung]][[en:Cyclicredundancycheck]][[es:Controlderedundanciacíclica]][[eu:CRC]][[fi:CRC]][[fr:Contrôlederedondancecyclique]][[he:בדיקתיתירותמחזורית]][[id:CRC]][[it:Cyclicredundancycheck]][[ja:巡回冗长検査]][[ko:순환중복검사]][[nl:CyclicRedundancyCheck]][[pl:CRC]][[pt:CRC]][[ru:Циклическийизбыточныйкод]][[simple:Cyclicredundancycheck]][[sk:Kontrolacyklickýmkódom]][[sv:CyclicRedundancyCheck]][[vi:CRC]]

Modbus RTU CRC校验码计算方法

在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。

CRC计算方法是:

1、  加载一值为0XFFFF的16位寄存器,此寄存器为CRC寄存器。

2、  把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的相异或,异或的结果仍存放于该CRC寄存器中。

3、  把CRC寄存器的内容右移一位,用0填补最高位,并检测移出位是0还是1。

4、  如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与0XA001进行异或。

5、  重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理。

6、  重复步骤2和5,进行通讯信息帧下一个字节的处理。

7、  将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换

8、  最后得到的CRC寄存器内容即为:CRC校验码

以上是关于计算机网络CRC检验中为啥选择16或32位效验码,效率最高?的主要内容,如果未能解决你的问题,请参考以下文章

计算CRC校验值(CRC16和CRC32)(网络传输检验)

python 通过crc32得到加密文件内容

LRC的效验码的计算方法

关于CRC效验

求助大神还都有哪些16位冗余校验计算方法,试过常见的几种CRC16都不对

串口通讯:请教报文里crc16检验