A. 计算机网络CRC检验中为什么选择16或32位效验码,效率最高
循环冗余校验(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)-\frac{1}{(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-1}x^{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_Semiconctor|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)||(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:Controlderendànciacíclica]][[cs:Cyklickýrendantnísoučet]][[de:ZyklischeRendanzprüfung]][[en:Cyclicrendancycheck]][[es:Controlderendanciacíclica]][[eu:CRC]][[fi:CRC]][[fr:Contrôlederedondancecyclique]][[he:בדיקתיתירותמחזורית]][[id:CRC]][[it:Cyclicrendancycheck]][[ja:巡回冗长検査]][[ko:순환중복검사]][[nl:CyclicRendancyCheck]][[pl:CRC]][[pt:CRC]][[ru:Циклическийизбыточныйкод]][[simple:Cyclicrendancycheck]][[sk:Kontrolacyklickýmkódom]][[sv:CyclicRendancyCheck]][[vi:CRC]]
B. 计算机网络原理的计算题(CRC校验和数据传输问题)
第一题:进行模2除法时被除数错了,应该是M*2^4,不是M*2^5,因为多项式是4阶的,在M后面添4个0
C. 计算机网络原理中求CRC校验码。
01100。算法你可以用手算,或者用代码计算,代码分按位和按字节。手算算法是:多项式为101101你在信息的后面补5个0信息码变为1101101100000这时开始用多项式对上面的信息码进行异或操作,要打的话很麻烦。我只把没一次运算的结果写一下1:011011(注意,前面一位已经为零,这时,要在此数后面补一个数,也就是说,现在已经对8为信息码操作了一位)移位以后变为110111。(此时的首位又为1,再与多项式异或,下面的类似)2:0110103:0110004:0111015:0101116:000011 注意此时的信息码已经被操作了5次了,就是说还有3位没有操作,这时把这个数左移3位就好了,因为他的前3位都为零,所以最后的crc码为01100整个要发送的数据为11011011+01100中间算的可能有错误,开始看crc的时候可能会很难懂,看看代码很不错的
D. 关于计算机网络循环冗余码怎么求求大神。、、
解出的R=0101(fcs)
输出2^nM+fas=1001110111010101
唔感觉是这样的
E. CRC算法模拟 计算机网络基础课程 高分求解 正解追加200
引言
CRC的全称为Cyclic Rendancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。实际上,除数据通信外,CRC在其它很多领域也是大有用武之地的。例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑。
差错控制理论是在代数理论基础上建立起来的。这里我们着眼于介绍CRC的算法与实现,对原理只能捎带说明一下。若需要进一步了解线性码、分组码、循环码、纠错编码等方面的原理,可以阅读有关资料。
利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为“生成多项式”。
1 代数学的一般性算法
在代数编码理论中,将一个码组表示为一个多项式,码组中各码元当作多项式的系数。例如 1100101 表示为
1·x6+1·x5+0·x4+0·x3+1·x2+0·x+1,即 x6+x5+x2+1。
设编码前的原始信息多项式为P(x),P(x)的最高幂次加1等于k;生成多项式为G(x),G(x)的最高幂次等于r;CRC多项式为R(x);编码后的带CRC的信息多项式为T(x)。
发送方编码方法:将P(x)乘以xr(即对应的二进制码序列左移r位),再除以G(x),所得余式即为R(x)。用公式表示为
T(x)=xrP(x)+R(x)
接收方解码方法:将T(x)除以G(x),如果余数为0,则说明传输中无错误发生,否则说明传输有误。
举例来说,设信息码为1100,生成多项式为1011,即P(x)=x3+x2,G(x)=x3+x+1,计算CRC的过程为
xrP(x) x3(x3+x2) x6+x5 x
-------- = ---------- = -------- = (x3+x2+x) + --------
G(x) x3+x+1 x3+x+1 x3+x+1
即 R(x)=x。注意到G(x)最高幂次r=3,得出CRC为010。
如果用竖式除法,计算过程为
1110
-------
1011 /1100000 (1100左移3位)
1011
----
1110
1011
-----
1010
1011
-----
0010
0000
----
010
因此,T(x)=(x6+x5)+(x)=x6+x5+x, 即 1100000+010=1100010
如果传输无误,
T(x) x6+x5+x
------ = --------- = x3+x2+x,
G(x) x3+x+1
无余式。回头看一下上面的竖式除法,如果被除数是1100010,显然在商第三个1时,就能除尽。
上述推算过程,有助于我们理解CRC的概念。但直接编程来实现上面的算法,不仅繁琐,效率也不高。实际上在工程中不会直接这样去计算和验证CRC。
下表中列出了一些见于标准的CRC资料:
名称 生成多项式 简记式* 应用举例
CRC-4 x4+x+1 ITU G.704
CRC-12 x12+x11+x3+x+1
CRC-16 x16+x12+x2+1 1005 IBM SDLC
CRC-ITU** x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
CRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
CRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP
* 生成多项式的最高幂次项系数是固定的1,故在简记式中,将最高的1统一去掉了,如04C11DB7实际上是104C11DB7。
** 前称CRC-CCITT。ITU的前身是CCITT。
2 硬件电路的实现方法
多项式除法,可用除法电路来实现。除法电路的主体由一组移位寄存器和模2加法器(异或单元)组成。以CRC-ITU为例,它由16级移位寄存器和3个加法器组成,见下图(编码/解码共用)。编码、解码前将各寄存器初始化为"1",信息位随着时钟移入。当信息位全部输入后,从寄存器组输出CRC结果。
3 比特型算法
上面的CRC-ITU除法电路,完全可以用软件来模拟。定义一个寄存器组,初始化为全"1"。依照电路图,每输入一个信息位,相当于一个时钟脉冲到来,从高到低依次移位。移位前信息位与bit0相加产生临时位,其中bit15移入临时位,bit10、bit3还要加上临时位。当全部信息位输入完成后,从寄存器组取出它们的值,这就是CRC码。
typedef unsigned char bit;
typedef unsigned char byte;
typedef unsigned short u16;
typedef union {
u16 val;
struct {
u16 bit0 : 1;
u16 bit1 : 1;
u16 bit2 : 1;
u16 bit3 : 1;
u16 bit4 : 1;
u16 bit5 : 1;
u16 bit6 : 1;
u16 bit7 : 1;
u16 bit8 : 1;
u16 bit9 : 1;
u16 bit10 : 1;
u16 bit11 : 1;
u16 bit12 : 1;
u16 bit13 : 1;
u16 bit14 : 1;
u16 bit15 : 1;
} bits;
} CRCREGS;
// 寄存器组
CRCREGS regs;
// 初始化CRC寄存器组:移位寄存器置为全"1"
void crcInitRegisters()
{
regs.val = 0xffff;
}
// CRC输入一个bit
void crcInputBit(bit in)
{
bit a;
a = regs.bits.bit0 ^ in;
regs.bits.bit0 = regs.bits.bit1;
regs.bits.bit1 = regs.bits.bit2;
regs.bits.bit2 = regs.bits.bit3;
regs.bits.bit3 = regs.bits.bit4 ^ a;
regs.bits.bit4 = regs.bits.bit5;
regs.bits.bit5 = regs.bits.bit6;
regs.bits.bit6 = regs.bits.bit7;
regs.bits.bit7 = regs.bits.bit8;
regs.bits.bit8 = regs.bits.bit9;
regs.bits.bit9 = regs.bits.bit10;
regs.bits.bit10 = regs.bits.bit11 ^ a;
regs.bits.bit11 = regs.bits.bit12;
regs.bits.bit12 = regs.bits.bit13;
regs.bits.bit13 = regs.bits.bit14;
regs.bits.bit14 = regs.bits.bit15;
regs.bits.bit15 = a;
}
// 输出CRC码(寄存器组的值)
u16 crcGetRegisters()
{
return regs.val;
}
crcInputBit中一步一步的移位/异或操作,可以进行简化:
void crcInputBit(bit in)
{
bit a;
a = regs.bits.bit0 ^ in;
regs.val >>= 1;
if(a) regs.val ^= 0x8408;
}
细心的话,可以发现0x8408和0x1021(CRC-ITU的简记式)之间的关系。由于我们是从低到高输出比特流的,将0x1021左右反转就得到0x8408。将生成多项式写成 G(x)=1+x5+x12+x16,是不是更好看一点?
下面是一个典型的PPP帧。最后两个字节称为FCS(Frame Check Sequence),是前面11个字节的CRC。
FF 03 C0 21 04 03 00 07 0D 03 06 D0 3A
我们来计算这个PPP帧的CRC,并验证它。
byte ppp[13] = {0xFF, 0x03, 0xC0, 0x21, 0x04, 0x03, 0x00, 0x07, 0x0D, 0x03, 0x06, 0x00, 0x00};
int i,j;
u16 result;
/////////// 以下计算FCS
// 初始化
crcInitRegisters();
// 逐位输入,每个字节低位在先,不包括两个FCS字节
for(i = 0; i < 11; i++)
{
for(j = 0; j < 8; j++)
{
crcInputBit((ppp[i] >> j) & 1);
}
}
// 得到CRC:将寄存器组的值求反
result = ~crcGetRegisters();
// 填写FCS,先低后高
ppp[11] = result & 0xff;
ppp[12] = (result >> 8) & 0xff;
/////////// 以下验证FCS
// 初始化
crcInitRegisters();
// 逐位输入,每个字节低位在先,包括两个FCS字节
for(i = 0; i < 13; i++)
{
for(j = 0; j < 8; j++)
{
crcInputBit((ppp[i] >> j) & 1);
}
}
// 得到验证结果
result = crcGetRegisters();
可以看到,计算出的CRC等于0x3AD0,与原来的FCS相同。验证结果等于0。初始化为全"1",以及将寄存器组的值求反得到CRC,都是CRC-ITU的要求。事实上,不管初始化为全"1"还是全"0",计算CRC取反还是不取反,得到的验证结果都是0。
4 字节型算法
比特型算法逐位进行运算,效率比较低,不适用于高速通信的场合。数字通信系统(各种通信标准)一般是对一帧数据进行CRC校验,而字节是帧的基本单位。最常用的是一种按字节查表的快速算法。该算法基于这样一个事实:计算本字节后的CRC码,等于上一字节余式CRC码的低8位左移8位,加上上一字节CRC右移8位和本字节之和后所求得的CRC码。如果我们把8位二进制序列数的CRC(共256个)全部计算出来,放在一个表里 ,编码时只要从表中查找对应的值进行处理即可。
CRC-ITU的计算算法如下:
a.寄存器组初始化为全"1"(0xFFFF)。
b.寄存器组向右移动一个字节。
c.刚移出的那个字节与数据字节进行异或运算,得出一个指向值表的索引。
d.索引所指的表值与寄存器组做异或运算。
f.数据指针加1,如果数据没有全部处理完,则重复步骤b。
g.寄存器组取反,得到CRC,附加在数据之后。
CRC-ITU的验证算法如下:
a.寄存器组初始化为全"1"(0xFFFF)。
b.寄存器组向右移动一个字节。
c.刚移出的那个字节与数据字节进行异或运算,得出一个指向值表的索引。
d.索引所指的表值与寄存器组做异或运算。
e.数据指针加1,如果数据没有全部处理完,则重复步骤b (数据包括CRC的两个字节)。
f.寄存器组的值是否等于“Magic Value”(0xF0B8),若相等则通过,否则失败。
下面是通用的CRC-ITU查找表以及计算和验证CRC的C语言程序:
// CRC-ITU查找表
const u16 crctab16[] =
{
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78,
};
// 计算给定长度数据的16位CRC。
u16 GetCrc16(const byte* pData, int nLength)
{
u16 fcs = 0xffff; // 初始化
while(nLength>0)
{
fcs = (fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xff];
nLength--;
pData++;
}
return ~fcs; // 取反
}
// 检查给定长度数据的16位CRC是否正确。
bool IsCrc16Good(const byte* pData, int nLength)
{
u16 fcs = 0xffff; // 初始化
while(nLength>0)
{
fcs = (fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xff];
nLength--;
pData++;
}
return (fcs == 0xf0b8); // 0xf0b8是CRC-ITU的"Magic Value"
}
使用字节型算法,前面出现的PPP帧FCS计算和验证过程,可用下面的程序片断实现:
byte ppp[13] = {0xFF, 0x03, 0xC0, 0x21, 0x04, 0x03, 0x00, 0x07, 0x0D, 0x03, 0x06, 0x00, 0x00};
u16 result;
// 计算CRC
result = GetCrc16(ppp, 11);
// 填写FCS,先低后高
ppp[11] = result & 0xff;
ppp[12] = (result >> 8) & 0xff;
// 验证FCS
if(IsCrc16Good(ppp, 13))
{
... ...
}
该例中数据长度为11,说明CRC计算并不要求数据2字节或4字节对齐。
至于查找表的生成算法,以及CRC-32等其它CRC的算法,可参考RFC 1661, RFC 3309等文档。需要注意的是,虽然CRC算法的本质是一样的,但不同的协议、标准所规定的初始化、移位次序、验证方法等可能有所差别。
结语
CRC是现代通信领域的重要技术之一。掌握CRC的算法与实现方法,在通信系统的设计、通信协议的分析以及软件保护等诸多方面,能发挥很大的作用。如在作者曾经设计的一个多串口数据传输系统中,每串口速率为460kbps,不加校验时误码率大于10-6,加上简单的奇偶校验后性能改善不很明显,利用CRC进行检错重传,误码率降低至10-15以下,满足了实际应用的要求。
F. 关于计算机网络的crc计算
我们知道,一台主机向另外一台主机发送报文的时候,需要一层层经过自己的协议栈进行数据封装,到达最后一层(四层协议的网络接口层)时需要在帧尾部添加FCS校验码(通过CRC算法得出)。当对端主机收到时,在接收端同样通过CRC算法进行验证,确认传输过程中是否出现错误。它只能确认一个帧是否存在比特差错,但没有提供解决措施。
循环冗余校验的原理
在发送端,先把数据划分为组(即:一帧)。假定每组 k 个比特。
在每组后面,添加供差错检测用的 n 位冗余码一起发送。即:实际发送长度为:k+n 比特。
发送前双方协商n+1位的除数P,方便接收方收到后校验。
给K比特的数据添加除数减一个0(P-1)作为被除数,与第三步确定的除数做“模2除法”。得出的余数即FCS校验序列,它的位数也必须是(P-1)。
将FCS校验序列添加至K个比特位的后面发送出去。
接收方对接收到的每一帧进行校验,若得出的余数 R = 0,则判定这个帧没有差错,就接受(accept)。若余数 R ≠ 0,则判定这个帧有差错,就丢弃。
对“模2除法”进行说明:
“模2除法”与“算术除法”类似,但它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。模2加法运算为:1+1=0,0+1=1,0+0=0,无进位,也无借位;模2减法运算为:1-1=0,0-1=1,1-0=1,0-0=0,也无进位,无借位。相当于二进制中的逻辑异或运算。
计算示例
那么接收方拿到的就是:101001001。再以它为被除数,1101为除数进行“模2除法”。
G. 求解,计算机网络技术基础详细过程!
1. 在CRC校验中。已知生成多项式是G(x)=x4+x3+1。要求写出信息1011001的CRC校验码。 解:
生成多项式G(x)=11001,为5位,校验余数取4位,按模2除法计算过程如下:
1101010 11001 10110010000
11001 11110
11001 011110 11001 011100 11001 1010 余数R(x)= 1010
CRC校验码=1011001 1010
2. 双方采用CRC循环校验码进行通信,已知生成多项式为x4+x3+x+1,接收到码字为10111010011。判断该信息有无错误。 解:
依题意,生成多项式G(x)=11011,如果信息正确,则模2除法余数应为0
1100101 11011 10111010011 11011 11000
11011 11100 11011 11111 11011 100 结果余数R(x)= 100不为零所以结果有错。
在一个带宽为 3KHZ、没有噪声的信道,能够达到的码元速率极限值为6kbps 码元速率是信道传输数据能力的极限,奈奎斯特(Nyquist)首先给出了无噪声情况下码元速率的极限值与信道带宽的关系:B=2H (Baud)其中,H是信道的带宽,也称频率范围,即信道能传输的上、下限频率的差值。由此可以推出表征信道数据传输能力的奈奎斯特公式:C=2•H•log2N (bps)对于特定的信道,其码元速率不可能超过信道带宽的2倍,但若能提高每个码元可能取的离散值的个数,则数据传输速率便可成倍提高。例如,普通电话线路的带宽约为3kHz,则其码元速率的极限值为6kBaud。若每个码元可能取得离散值的个数为32(即N=32),则最大数据传输速率可达C=2*3k*log2 32=30kbps。
实际的信道总要受到各种噪声的干扰,香农(Shannon)则进一步研究了受随机噪声干扰的信道的情况,给出了计算信道容量的香农公式: C=H*log2(1+S/N) (bps)其中,S表示信号功率,N为噪声功率,由此可见,只要提高信道的信噪比,便可提高信道的最大数据传输速率
希望能帮到你
H. 计算机网络问题,急,,,
2017年12月13日星期三,
这里需要强调一点,生成多项式(generator polynomial)和多项式不是一个概念,这里需要注意。我个人的理解是你要进行几位的CRC校验,就需要几位的生成多项式(generator polynomial),但还收到生成多项式(generator polynomial)的第一位必须为1的限制,因此生成的多项式还需要注意这一点。原始信息所对应的多项式和生成多项式(generator polynomial)不是一个概念。
首先,我们要知道,任何一串二进制数都可以用一个多项式表示:且这串二进制数的各位对应多项式的各幂次,多项式中假如有此幂次项(比如多项式汇中有幂次项x^2对应二进制串码中从右至左的第三位二进制数一定为1.因为右数第一位的幂次项为x^0,右数第二位的幂次项为x^1),则对应二进制数串码中此位置的1,无此幂次项对应0。
举例:代码1010111对应的多项式为x^6+x^4+x^2+x+1,若我们将缺失的幂次项补全的话就有x^6+(x^5)+x^4+(X^3)+x^2+x+1,又因为x^5和X^3所对应的二进制位为0,不记入多项式中,因此有x^6+x^4+x^2+x+1,就是表示 1010111这个串码。
而多项式为x^5+x^3+x^2+x+1的完整多项式为x^5+(x^4)+x^3+x^2+x+1正好对应二进制串码101111,而x^4对应的二进制串码中右数第五位(左数第二位)为0,不记入多项式中,因此,101111可以使用多项式x^5+x^3+x^2+x+1来表示。
通过上述两个多项式的例子,可以看出,当多项式中的幂次项所对应的那一位二进制为1时,多项式中的那一个幂次项存在,而当二进制串码中的某位为0时,对应的多项式幂次项忽略不记录,例如,10111 1因为从左向右第二位是0,因此对应的多项式分子x^4就没有被记录到多项式中,
书面的说法是:
多项式和二进制数有直接对应关系:X的最高幂次对应二进制数的最高位,以下各位对应多项式的各幂次,有此幂次项对应1,无此幂次项对应0。可以看出:X的最高幂次为R,转换成对应的二进制数有R+1位,
我们现在来看题目中generator plynomial (生成多项式)is X^4+x^2+1,最高幂次是4,因此,其表示的二进制为(4+1=5)5位,
且通过crc的原理,我们知道,循环冗余校验码(CRC)是由两部分组拼接而成的,
第一部分是信息码,
第二部分是校验码,
可得公式:
CRC=信息码+校验码,
很明显校验码是跟在信息码之后的,所以,题目中1101011011中左数的那5位是真正传输的信息(信息码),即actual bit string transmitted(实际传输的信息位流)是11010,而后面的5位(11011)是校验码,
接下来我们结合上面的内容来理解对CRC的定义:
循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。对于一个给定的(N,K)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。 校验码的具体生成过程为:假设要发送的信息用多项式C(X)表示,将C(x)左移R位(可表示成C(x)*2^R),这样C(x)的右边就会空出R位,这就是校验码的位置。用 C(x)*2^R 除以生成多项式G(x)得到的余数就是校验码。
另一个定义:
利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为“生成多项式”。
再看另一个描述,在代数编码理论中,将一个码组表示为一个多项式,码组中各码元当作多项式的系数。例如 1100101 表示为1·x^6+1·x^5+0·x^4+0·x^3+1·x^2+0·x^1+1,即 x^6+x^5+x^2+1。
设,编码前的原始信息多项式为P(x),P(x)的最高幂次加1等于k(这里的K就是整个原始信息的二进制编码的长度,以上例1100101为例,此串二进制编码的最高位对应的多项式幂次为6,根据定义得K=6+1=7,正好是此串二进制编码的长度,);
设,生成多项式为G(x),G(x)的最高幂次等于r,这个r可以随意指定,也就是r可以不等于K,但指定r时,必须满足生成多项式G(x)最高位必须为1的条件,
设,CRC多项式为R(x)。:将P(x)乘以x^r(即对应的二进制码序列左移r位),再除以G(x),所得余式即为R(x)。
设,编码后的带CRC的信息多项式为T(x)。:用公式表示为T(x)=x^r*P(x)+R(x),翻译过来就是,编码后的带CRC校验的多项式由左移了r位的原始信息P(x)后接CRC的校验码R(x)组成,
而在接收端,是使用T(x )去除G(x),若无余数,则表示接收正确。就是接收端使用接收到的信息T(x )去除和发送端约好的生成多项式G(x),若除尽没有余数则表示信息正确接收。
我们再来看本题,
题中给出已传输的信息为:1101011011,即T(x )=1101011011;
而generator polynomial 生成多项式是:x^4+x^2+1,即G(x)=10101;
那么,我们来使用T(x )除以G(x)=110,根据上面的定义,我们知道,出现了没有除尽的情况,有余数,余数为110,则说明信息11010在传递过程出现了错误,而题目中给出,若将此信息串码的左数第三位进行翻转,则接收到的信息为:1111011011,那么,
T(x )=1111011011,
则,再通过T(x )除以G(x)进行校验运算后,得到余数1,没有除尽
即T(x )除以G(x)=1,
所以没有通过CRC校验,此时,接收端能发现这个错误,
但是,如果我们将此串数据的左数第三位和最后一位同时翻转,得到1111011010,那么再经过T(x )除以G(x)的接收端校验后,除尽了,余数为0,则,此时,因为T(x )除以G(x)=0,通过了接收端的校验,因此,接收端并不能发现这个错误,以为是收到了正确的串码:11110,但实际上我们发送的串码是:11010,
最后,我们再来研究一下,T(x )是怎么除G(x)的,实际上我们必须清楚,这里的除法实际上并不是我们传统意义上的十进制除法,而是两个二进制的“按位异或”(请注意每步运算都是先进行高位对齐的。)的算法,在二进制数运算中,这被称为模二除运算,
来看两个例子,
【例一】假设使用的生成多项式是G(X)=X3+X+1。4位的原始报文为1010,求编码后的报文。
解:
1、将生成多项式G(X)=X^3+X+1转换成对应的二进制除数1011。
R=3,R就是生成多项式的最高次幂,
2、此题生成多项式有4位(R+1)(注意:通过对生成多项式计算所得的校验码为3位,因为,生成多项式的R为生成多项式的最高次幂,所以校验码位数是3位),要把原始报文C(X)【这里的C(X)就是1010】左移3(R)位变成1010 000
3、用生成多项式对应的二进制数对左移3位后的原始报文进行模2除(高位对齐),相当于按位异或:
1010000
1011
------------------
0001000, 请注意这里,通过第一次除法,也就是模2除(高位对齐)的运算,将两个二进制代码进行了高位对齐后的按位异或的操作后,得到0001000即1000,接下来,需要进行第二次除法,即使用第一步得到的二进制数1000去除1011【G(x)】,则有下面的式子,
1000
1011
------------------
0011,请注意,结果为0011,也可以写成11,但是我们由上面得知,由生成多项式G(X)=X^3+X+1,已经确定了校验位是3位,因此,
得到的余位011,所以最终编码为:1010 011。
例二:
信息字段代码为: 1011001;对应的原始多项式P(x)=x6+x4+x3+1
假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为: 11001,又因为g(x)最高次幂为4,因此可以确定校验位是4位,
根据CRC给生成多项式g(x)定义的规则,将原始代码整体左移4位,这样在原始数据后面多出4位校验位的位置,即x^4*P(x),得到:10110010000;
接下来使用10110010000去除以g(x),得到最终的余数1010,并与原始信息组成二进制串码:1011001 1010发送出去,
接收方:使用相同的生成多项式进行校验:接收到的字段/生成码(二进制除法)
如果能够除尽,则正确,
给出余数(1010)的计算步骤:
除法没有数学上的含义,而是采用计算机的模二除法,即除数和被除数做异或运算。进行异或运算时除数和被除数最高位对齐,按位异或。
10110010000
^11001
--------------------------
01111010000 ,这里进行第一次按位异或,得到01111010000,即1111010000,将1111010000再去除以11001,如下步骤,
1111010000
^11001
-------------------------
0011110000,进行了第二次模2除后,得到0011110000,即11110000,将
11110000去除11001,
11110000
^11001
--------------------------
00111000,第三次摸2除,得到00111000,即111000,用
111000去除11001,
111000
^11001
-------------------
001010,进行第四次模2除后,得到最终的余数,001010,即1010,
则四位CRC校验码就为:1010。
I. 已知信息码元为15为线性分码组,监督码元怎么求
使用二进制转换。监督码元—指经过差错编码后在信息码元基础上增加的冗余码元。在数字通信中常常用时间间隔相同的符号来表示一个二进制数字,这时使用二进制转换信号码为15码元会产生间隔。而这个间隔被称为监督码元长度。
J. 常用的网络协议有哪些
常用的网络协议有TCP/IP协议、IPX/SPX协议、NetBEUI协议等。
1.TCP/IP协议
TCP/IP协议用得最多,只有TCP/IP协议允许与internet进行完全连接。现今流行的网络软件和游戏大都支持TCP/IP协议。
2.IPX/SPX协议
IPX/SPX协议是Novell开发的专用于NetWare网络的协议,大部分可以联机的游戏都支持IPX/SPX协议,例如星际、cs。虽然这些游戏都支持TCP/IP协议,但通过IPX/SPX协议更省事,不需要任何设置。IPX/SPX协议在局域网中的用途不大。它和TCP/IP协议的一个显着不同是它不使用ip地址,而是使用mac地址。
为了能进行通信,规定每个终端都要将各自字符集中的字符先变换为标准字符集的字符后,才进入网络传送,到达目的终端之后,再变换为该终端字符集的字符。当然,对于不相容终端,除了需变换字符集字符外还需转换其他特性,如显示格式、行长、行数、屏幕滚动方式等也需作相应的变换。