CRC专题

CRC专题
CRC专题

1 前言

数据损坏是与数据传输和存储有关的首要问题。只要是在通道上传输数据,就总会有出现某些错误的有限概率。关键是接收模块要能区分无错消息和有错消息。数据通信中常用的检错方法包括奇偶码、重复码校验、恒比码校验、行列冗余码校验、汉明码和循环冗余校验(CRC)等。这些方法都是增加数据的冗余量,将校验码和数据一起发送到接受端。接受端对接受到的数据进行相同校验, 再将得到的校验码和接受到的校验码比较, 如果二者一致则认为传输正确。但

这些方法都有各自的缺点, 误判的概率比较高。循环冗余码CRC校验技术广泛应用于测控及通信领域, 是当前在信源编码中用来降低误码率的有效手段之一。数字通信中的CRC实现主要分为硬件实现

和软件实现两类。在高速通信系统中, 为了适应速度和通信传输的要求,CRC 校验部分往往都设计

为串行输入的硬件实现。

2 原理

CRC 的全称为Cyclic Redundancy Check, 即循环冗余校验。它是一类重要的线性分组码,

编码和解码方法简单, 检错和纠错能力强, 在通信领域广泛地用于实现差错控制。CRC 校验的基本思想是利用线性编码理论, 在发送端根据要传送的k位二进制码序列, 以一定的规则产生一个校验用的r 位监督码( CRC 码) , 附在原始信息后边, 构成一个新的二进制码序列数共k+r 位, 然后发送出去。在接收端, 根据信息码和CRC 码之间所遵循的规则进行检验, 以确定传送中是否出错。这个规则, 在差错控制理论中称为“生成多项式”。

加法和减法运算是用模2 算法执行,也就是说,这两种运算与“异或”(XOR)运算相同。除了没有进位,多项式算法中的两数相加与普通二进制算法中的多数相加相同。

例如:二进制消息流11001011 表达为x7+x6+x3+x+1。传输点与接收点约定一个固定的生成器多项式,这是CRC 计算的关键参数。将数据解释为一个多项式的系数,用一个给定的生成器多项式除这些系数。除得的余数就是CRC。假设有一个m 位消息序列和一个r 阶生成器多项式,发射器创建一个n 位(n=m+r)序列,称为帧校验序列(FCS),使这个(m+r)位合成帧可以被一个预先确定的序列整除。

发射器将r 个0 位附加到m 位的消息,并且用生成器多项式除所得m+r-1 阶多项式。这样可得到一个阶数等于或小于(r-1)的余数多项式。该余数多项式有r 个系数,这些系数形成校验和。将商丢弃。传输的数据是原m 位消息后附r 位校验和。

在接收器上,可以按以下两种标准方法之一评估所接收数据的有效性:

(1) 对收到的前m 个位再次计算校验和,然后与收到的校验和(收到的后r 个位)进行比较;

(2) 对收到的全部(m+r)个位计算校验和,然后与一个0 余数进行比较。

为了说明第二种方法如何得出0 余数,我们做如下约定:

M=消息的多项表达式;R=发射器上所算得余数的多项表达式;G=生成器多项式;Q=用G 除M 得到的商。传输的数据对应于多项式Mx r-R。变量x r表示消息为容纳校验和而产生的一个r位移位。我们知道:

Mx r=QG+R

在发射器上将校验和R 附加到消息中相当于从消息中减去余数。于是,传输的数据变为Mx r-R=QG,这显然是G 的倍数。这就是我们在第二种情况下得到0 余数的过程。

不过,这一过程对所传输数据中首0 位和尾0 位的个数不敏感。换句话说,无论消息插入还是删除尾0 位,余数都保持为0,从而使错误漏检,这表明不会复原成同样的位序列。下面介绍一种克服这一缺点的变通办法。

3 剩余法

实际上,校验和经过反演后才附加到消息中。这就使接收器上算出的余数(超过m+r 位)不为0。在这类情况下,接收器上得到的余数是一个固定值,称为多项式的剩余值。

假定% 符号在下列表达式中表示模运算。对于未经反演附加校验和的情况: (Mx r-R)x r%G=0 (注:接收端移位),在这种情况下,接收器会执行与发射器一样的移位运算。

现在,考虑校验和在发射器上经反演后附加到消息流的情况:(Mx r-R c)x r%G 。其中,R c表示经过反演的校验和。还可以将其写成:(Mx r– R + (x r-1+ ... + x + 1)) x r % G。一个位的反码与其对1 异或运算的结果相同。这里的+ 号表示模2 算法中的加法(请注意,在模 2 算法中,加法和减法运算相同)。

在这种情况下,余数与以下表达式相同:(x r-1+ ... + x + 1) x r % G,对于给定的生成器多项式来说,此表达式的计算结果将是一个常数。

最常用的CRC 32 生成器多项式在十六进制中是04C11DB7。与CRC-32 对应的常数剩余值在十六进制中是C704DD7B。对于给定的生成器多项式G 来说,无论在输入端提供何种数据样式,剩余值仍为常数。

4 硬件实现

4.1移位算法

CRC 校验和的计算是多项式除法过程。在硬件中实现该过程需要使用一个移位寄存器(亦称CRC 寄存器)。该移位寄存器的长度与生成器多项式的阶数相同。

CRC 计算过程如下:

(1) 初始化CRC寄存器;

(2) 持续获取消息位,直到获得所有消息位。如果CRC 寄存器中的高阶位是1,则向左移一位,并且将其结果与G 进行异或运算。否则,仅向左移一位。

对给定消息完成所有这些步骤后,CRC 寄存器中剩下的就是余数。

可以用一种称为线性反馈移位寄存器(LFSR)的电路执行这些步骤。图1 所示为用CRC32 多项式计算CRC 的LFSR 实现方法。请注意,异或门的布局取决于生成器多项式中项值为1 的对应项的系数。图中的编号方框各代表一个存储元件(触发器)。

简单的LFSR。这种电路虽然实现起来简单,对任意长度生成多项式的g(x)都适用,但算法一次只能处理一位数据,效率太低,对于一个n 位数据流来说,要占用n 个时钟周期来计算CRC 值,主要用于串行通信中,不适合高速通信的场合。

4.2 查找表法

在必须以较高速度处理数据帧的高速数据网络应用中,这样LFSR电路n个延时周期的延迟是无法忍受的。这类高速网络应用迫切需要对并行数据流实现CRC 生成和校验。查表法就是基于该应用的一个改进算法。

这种方法是事先制作出一表格,将所有的信息组对应的校验元按次序排序起来,这样只要识别读入的信息组是什么就能用一条指令找到对应的校验元。假设对于每一个段多项式,都能从一张指定的表中找到对应的余式.那么余式的实现就控制在一个工作时钟内实现。信息分为P段,明显地,仅仅P个工作时钟就能完成各个余式的计算。如果P越小,需要的时间就越短,这种方法在时间上有很大的优越性,但是前提是要有满足存放余式表的存储器。因为对于任一段多项式都要有对应的余式,设每段长为m,在二进制系统中。则共有2m个不同段的多项式,那么需要的存储器大小就为:

reg_num=2m

其中reg_num为存储器的大小,m为段的长度。上式表明了分段大小与存储器两者的矛盾关系,要缩短时间,段数P就得减少,段的长度m就增长,存储单元数量就会以指数增加。

在实际应用中,采用折中的方法来优化算法。用查表法的实现过程主要分为以下几个步骤。

第一步:初始化。存储单元CRC(CRC存放着校验元)初始为零。

第二步:CRC的内容与输入端的信息位异或后得到的结果存放到存储单元CANDM中。

第三步:根据CANDM的内容从软件表中查找对应的余式子,并把该余式子更新到存储单元CRC中去。

第四步:判断是否还有待处理的子字符串,如果有则跳到第二步;反之将CRC中的内容送到输出端,然后把CRC置零。

该算法事先把待校验的信息码的所有CRC码全部计算出来,放在一个表里,编码时只要根据信息码从表中找出对应的值即可。因此这种算法执行速度快,适合于高速通信场合,但由于需要大容量的存储表,花费的资源较移位算法要多。

4.3 公式法

公式法与查表算法一样,也是以字节数据为输入,采用递推算法,不同之处在于公式法使用公式实时计算CRC码,从而省去了查找表,不仅节省了硬件存储资源,还能进一步提高系统的运行速度。

根据上面的分析与公式推导,可以得到CRC码的产生与校验算法。设发送的字节矩阵为

M k-1,附加CRC校验码后的增广矩阵M k,其初始值为[M k-1 :00H];而接受的字节矩阵记作N k ,则发送端的CRC码的产生于接收端CRC校验码算法可以表述为:

1. CRC寄存器C(x)初始化为00H,计数器i初始化为0;

2. 输入第i个字节数据,按照上面的递推公式计算余式R i(x),并存入CRC寄存器C(x),计数器加1;

3. i是否小于k,若是则返回第二步,否则继续下一步;

4. 输出CRC寄存器的值C(x);

4.4 总结

随着软、硬件技术的不断发展,传统的CRC算法被不断地改进完善,新的算法不断被提出. 从本质上说,前边谈到的移位算法即是串行算法,甚至干脆称之为比特流算法,而后边所说的查表算法和公式法则为并行算法,串行算法虽然速度较慢,效率不高,但算法原理简单明了,易于硬件实现,加上串行通信领域的不可替代,于是有了存在的理由。并行算法的突出优势在速度快,当然它也为此付出了代价——花费的硬件资源量较大. 公式法的出现,则不仅进一步加大了并行算法高速的优势,还明显地降低了硬件的开销,因此可以认为是前景较好的一种实现算法。考虑到并行算法的电路实现的本质是以组合逻辑完成信号的处理过程:对于前边谈到的查表算法,是以硬件资源为代价,不予逻辑化简的实现方法,如同用ROM 实现组合逻辑功能。对于后来提出的公式算法,则大幅度地削减了硬件逻辑资源的闲置占用,故而不仅能明显降低成本还能有效地提高运算的速度,但其采用的递推算法却不能确保实现逻辑的最简,因而在顾及减轻设计运算量的同时也付出了一定的硬件代价。此外公式算法还存在须针对大小不同

的数据块、选取生成多项式的不同具体推算出相关的硬件实现电路的不足。

CRC16校验程序

CRC16校验程序 -------------------------------------------------------------------------------- 作者:转载 //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的3种 //实现方法进行测试。方法1选用了一种常见的查表方法,类似的还有512字 //节、256字等查找表的,至于查找表的生成,这里也略过。 // ---------------- POPULAR POLYNOMIALS ---------------- // CCITT:x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POLYNOMIALS 0x8005 // -------------------------------------------------------------- // CRC16计算方法1:使用2个256长度的校验表 // -------------------------------------------------------------- const BYTE chCRCHTalbe[] = // CRC 高位字节值表{ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; const BYTE chCRCLTalbe[] = // CRC 低位字节值表{ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,

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)得到的余数就是校验码。 编辑本段 几个基本概念 1、多项式与二进制数码 多项式和二进制数有直接对应关系:x的最高幂次对应二进制数的最高位,以下各位对应多项式的各幂次,有此幂次项对应1,无此幂次项对应0。可以看出:x的最高幂次为R,转换成对应的二进制数有R+1位。 多项式包括生成多项式G(x)和信息多项式C(x)。 如生成多项式为G(x)=x^4+x^3+x+1,可转换为二进制数码11011。 而发送信息位1111,可转换为数据多项式为C(x)=x^3+x^2+x+1。 2、生成多项式 是接受方和发送方的一个约定,也就是一个二进制数,在整个传输过程中,这个数始终保持不变。 在发送方,利用生成多项式对信息多项式做模2除生成校验码。在接受方利用生成多项式对收到的编码多项式做模2除检测和确定错误位置。 应满足以下条件: a、生成多项式的最高位和最低位必须为1。 b、当被传送信息(CRC码)任何一位发生错误时,被生成多项式做除后应该使余数不为0。 c、不同位发生错误时,应该使余数不同。 d、对余数继续做除,应使余数循环。 3 CRC码的生成步骤 1、将x的最高次幂为R的生成多项式G(x)转换成对应的R+1位二进制数。 2、将信息码左移R位,相当与对应的信息多项式C(x)*2的R次方。 3、用生成多项式(二进制数)对信息码做除,得到R位的余数。 4、将余数拼到信息码左移后空出的位置,得到完整的CRC码。 【例】假设使用的生成多项式是G(x)=x^3+x+1。4位的原始报文为1010,求编码后的报文。 解: 1、将生成多项式G(x)=x^3+x+1转换成对应的二进制除数1011。 2、此题生成多项式有4位(R+1),要把原始报文C(x)左移3(R)位变成1010000 3、用生成多项式对应的二进制数对左移3位后的原始报文进行模2除,相当于按位异或: 1010000

CRC校验原理及步骤

C R C校验原理及步骤 This model paper was revised by the Standardization Office on December 10, 2020

CRC校验原理及步骤 什么是CRC校验 CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。 CRC校验原理: 其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。 模2除法: 模2除法与算术除法类似,但每一位除的结果不影响其它位,即不向上一位借位,所以实际上就是异或。在循环冗余校验码(CRC)的计算中有应用到模2除法。 例: CRC校验步骤:

CRC校验中有两个关键点,一是预先确定一个发送送端和接收端都用来作为除数的二进制比特串(或多项式),可以随机选择,也可以使用国际标准,但是最高位和最低位必须为1;二是把原始帧与上面计算出的除数进行模2除法运算,计算出CRC码。 具体步骤: 1. 选择合适的除数 2. 看选定除数的二进制位数,然后再要发送的数据帧上面加上这个位数-1位的0,然后用新生成的帧以模2除法的方式除上面的除数,得到的余数就是该帧的CRC校验码。注意,余数的位数一定只比除数位数少一位,也就是CRC校验码位数比除数位数少一位,如果前面位是0也不能省略。 3. 将计算出来的CRC校验码附加在原数据帧后面,构建成一个新的数据帧进行发送;最后接收端在以模2除法方式除以前面选择的除数,如果没有余数,则说明数据帧在传输的过程中没有出错。 CRC校验码计算示例: 现假设选择的CRC生成多项式为G(X)= X4+ X3+ 1,要求出二进制序列的CRC校验码。下面是具体的计算过程: ①将多项式转化为二进制序列,由G(X)= X4+ X3+ 1可知二进制一种有五位,第4位、第三位和第零位分别为1,则序列为11001 ②多项式的位数位5,则在数据帧的后面加上5-1位0,数据帧变为,然后使用模2除法除以除数11001,得到余数。【补几位0与x的最高次幂相同,模除就是进行异或】

CRC校验解读

三种常用的CRC16校验算法的C51程序的优化2009-10-10 09:34:17| 分类:技术知识| 标签:|字号大 CRC校验又称为循环冗余校验,是数据通讯中常用的一种校验算法。它可以有效的判别出数据在传输过程中是否发生了错误,从而保障了传输的数据可靠性。 CRC校验有多种方式,如:CRC8、CRC16、CRC32等等。在实际使用中,我们经常使用CRC16校验。CRC16校验也有多种,如:1005多项式、1021多项式(CRC-ITU)等。在这里我们不讨论CRC算法是怎样产生的,而是重点落在几种算法的C51程序的优化上。 计算CRC校验时,最常用的计算方式有三种:查表、计算、查表+计算。一般来说,查表法最快,但是需要较大的空间存放表格;计算法最慢,但是代码最简洁、占用空间最小;而在既要求速度,空间又比较紧张时常用查表+计算法。 下面我们分别就这三种方法进行讨论和比较。这里以使用广泛的51单片机为例,分别用查表、计算、查表+计算三种方法计算1021多项式(CRC-ITU)校验。原始程序都是在网上或杂志上经常能见到的,相信大家也比较熟悉了,甚至就是正在使用或已经使用过的程序。 编译平台采用Keil C51 7.0,使用小内存模式,编译器默认的优化方式。 常用的查表法程序如下,这是网上经常能够看到的程序范例。因为篇幅关系,省略了大部分表格的内容。 code unsigned int Crc1021Table[256] = { 0x0000, 0x1021, 0x2042, 0x3063,... 0x1ef0 }; unsigned int crc0(unsigned char *pData, unsigned char nLength) { unsigned int CRC16 = 0;

CRC校验是什么意思

寄给朋友 请问CRC校验是什么意思,为什么我安装某个软件时,它提示“installer crc invalid呢?怎样可以关闭呢? --- 作者:xyty时间:2002-12-309:49:00来自:211.146.xxx.xxx 正确指数:0作者:shock时间:2002-12-3010:17:00来自:61.172.xxx.xxx CRC的原理。 (由于CRC实现起来有一定的难度,所以具体怎样用它来保护文件,留待下一节再讲。) 首先看两个式子: 式一:9/3=3(余数=0) 式二:(9+2)/3=3(余数=2) 在小学里我们就知道,除法运算就是将被减数重复地减去除数X次,然后留下余数。 所以上面的两个式子可以用二进制计算为:(什么?你不会二进制计算?我倒~~~) 式一: 1001-->9 0011--->3 --------- 0110-->6 0011--->3 --------- 0011-->3 0011--->3 --------- 0000-->0,余数 一共减了3次,所以商是3,而最后一次减出来的结果是0,所以余数为0 式二:

1011-->11 0011--->3 --------- 1000-->8 0011--->3 --------- 0101-->5 0011--->3 --------- 0010-->2,余数 一共减了3次,所以商是3,而最后一次减出来的结果是2,所以余数为2 看明白了吧?很好,let’s go on! 二进制减法运算的规则是,如果遇到0-1的情况,那么要从高位借1,就变成了(10+0)-1=1 CRC运算有什么不同呢?让我们看下面的例子: 这次用式子30/9,不过请读者注意最后的余数: 11110-->30 1001--->9 --------- 1100-->12(很奇怪吧?为什么不是21呢?) 1001--->9 -------- 101-->3,余数-->the CRC! 这个式子的计算过程是不是很奇怪呢?它不是直接减的,而是用XOR的方式来运算(程序员应该都很熟悉XOR吧),最后得到一个余数。 对啦,这个就是CRC的运算方法,明白了吗?CRC的本质是进行XOR运算,运算的过程我们不用管它,因为运算过程对最后的结果没有意义;我们真正感兴趣的只是最终得到的余数,这个余数就是CRC值。 进行一个CRC运算我们需要选择一个除数,这个除数我们叫它为“poly”,宽度W就是最高位的位置,所以我刚才举的例子中的除数9,这个poly1001的W是3,而不是4,注意最高位总是1。(别问为什么,这个是规定) 如果我们想计算一个位串的CRC码,我们想确定每一个位都被处理过,因此,我们要在目标位串后面加上W个0位。现在让我们根据CRC的规范来改写一下上面的例子: Poly=1001,宽度W=3 位串Bitstring=11110 Bitstring+W zeroes=11110+000=11110000 11110000

crc校验原理

校验原理 1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。 2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。 3、CRC码集选择的原则:若设码字长度为N,信息字段为K位,校验字段为R 位(N=K+R),则对于CRC码集中的任一码字,存在且仅存在一个R次多项式g(x),使得 V(x)=A(x)g(x)=x R m(x)+r(x); 其中: m(x)为K次信息多项式, r(x)为R-1次校验多项式, g(x)称为生成多项式: g(x)=g0+g1x+g2x2+...+g(R-1)x(R-1)+g R x R 发送方通过指定的g(x)产生CRC码字,接收方则通过该g(x)来验证收到的CRC 码字。 4、CRC校验码软件生成方法: 借助于多项式除法,其余数为校验字段。 例如:信息字段代码为: 1011001;对应m(x)=x6+x4+x3+1 假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为: 11001 x4m(x)=x10+x8+x7+x4对应的代码记为:10110010000; 采用多项式除法: 得余数为: 1010 (即校验字段为:1010) 发送方:发出的传输字段为: 1 0 1 1 0 0 1 1 0 10

信息字段校验字段 接收方:使用相同的生成码进行校验:接收到的字段/生成码(二进制除法)如果能够除尽,则正确,

CRC校验原理分析

CRC校验 校验原理: 1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。 2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。 3、CRC码集选择的原则:若设码字长度为N,信息字段为K位,校验字段为R 位(N=K+R),则对于CRC码集中的任一码字,存在且仅存在一个R次多项式g(x),使得 V(x)=A(x)g(x)=x R m(x)+r(x); 其中: m(x)为K次信息多项式, r(x)为R-1次校验多项式, g(x)称为生成多项式: g(x)=g 0+g 1 x+g 2 x2+...+g (R-1) x(R-1)+g R x R 发送方通过指定的g(x)产生CRC码字,接收方则通过该g(x)来验证收到的CRC 码字。 4、CRC校验码软件生成方法: 借助于多项式除法,其余数为校验字段。 例如:信息字段代码为: 1011001;对应m(x)=x6+x4+x3+1 假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为: 11001 x4m(x)=x10+x8+x7+x4对应的代码记为:10110010000; 采用多项式除法: 得余数为: 1010 (即校验字段为:1010)

发送方:发出的传输字段为: 1 0 1 1 0 0 1 1 0 10 信息字段校验字段 接收方:使用相同的生成码进行校验:接收到的字段/生成码(二进制除法)如果能够除尽,则正确,

crc校验详解

CRC校验专题 以CRC-16为例,说明CRC的计算过程: 1.设置CRC寄存器,并给其赋值FFFF(hex)。 2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。 3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。 4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。 5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。 6.重复第2至第5步直到所有数据全部处理完成。 7.最终CRC寄存器的内容即为CRC值。 翻译: 1.意思是首先寄存器中的值是1111111111111111 2.数据第一个字节一个字节=8位用二进制表示就是【00000000-11111111】之间用 这个数值跟寄存器中的16个1中的后8位进行异或(异或不知道什么意思的自己查简单理解就是同为0 异为1)然后把这个数值保存到寄存器中 3.判断最后一位是否为0 如果为0寄存器中的值向右移动一位前面补零如果为1 拿 寄存器中的值与多项式进行异或。 4.检查当前寄存器中的最后一位如果是0 重复第三步;如果是寄存器中的值与多项式 进行异或 5.重复3与4直到8此移位完成。 6.重复第2到第五步知道正规数组的数据验证完成 7.最终计算出的就是CRC的值 实例: 实例byte[] bufs=new byte[]{0x2f,0x12,0x31} crc16 多项式码假设是0x8408 二进制形式就是1000010000001000 1crc=0xffff; 用二进制表示就是1111111111111111 2拿出bufs中第一个字节0x2f 二进制表示00101111 跟寄存器中的后8位进行异或得到1111111111010000 3判断CRC寄存器中最后一位当前为0 寄存器右移一位得到0111111111101000 (如果为1就与多项式进行异或) 4判断当前寄存器中的值当前最后一位为0 所以重复第三步继续右移得到0011111111110100 最后还是0 在重复第三步0001111111111010 最后还是0 继续第三步0000111111111101 这时最后一位为1了这时与多项式进行异或得到1011101111111001 5重复判断知道判断完8次 6然后再重复第2到第5步直到上面数组中的bufs中三个字节验证完 7最终寄存器中的值就是crc值 下面进行实战C# code 分析

CRC8校验分析(修正版)

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。(网上流行的这一篇文章,前后两种算法得出来的CRC校验码并不一样,经过多次比对,发现查表法算出来的是正确的.一般性算法却不对,最后总结出来的是每一字节的被除数要反过来读取,算完后余数[即CRC码]也要反过来读取才对,不知何故,如果你懂,请发博文告诉大家.) CRC校验可以简单地描述为:例如我们要发送一些数据(信息字段),为了避免一些干扰以及在接收端的对读取的数据进行判断是否接受的是真实的数据,这时我们就要加上校验数据(即CRC校验码),来判断接收的数据是否正确。在发送端,根据要传送的k位二进制码序列,以一定的规则(CRC校验有不同的规则。这个规则,在差错控制理论中称为“生成多项式”。)产生一个校验用的r位校验码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共 k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则(即与发送时生成CRC校验码相同的规则)进行检验,校验采用计算机的模二除法,即除数和被除数(即生成多项式)做异或运算,进行异或运算时除数和被除数最高位对齐,进行按位异或运算,若最终的数据能被除尽,则传输正确;否则,传输错误。 CRC8即最终生成的CRC校验码为1字节,其生成多项式,生成多项式为g(x)=x8+x5+x4+1,相当于g(x)=1·x8+0·x7+0·x6+1·x5+1·x4+0·x3+0·x2+0·x1+1·x0,即对应的二进制数为100110001。 CRC8校验算法: 1.CRC8校验的一般性算法: 例如:信息字段代码为: 0X01 0X02 ————对应m(x)=x8+x (00000001) (00000010) 反过来读取,即为10000000 01000000 生成多项式为:g(x)=x8+x5+x4+1 ————对应g(x)的二进制代码为:100110001 现在我们将要对2字节数据0x0102生成CRC8校验码,并最终将生成的1字节CRC校验码跟在0x0102的后面,即0x01 02 ##,(##即8为CRC码),最终生成的3字节数据就是经CRC8校验生成的数据。 先计算x8m(x)=x16+x9,对应的2进制数为:10000000 01000000 00000000 。可以看到这样运算所得到的结果其实就是将信息字段代码的数左移8位。因为最终要将生成的8位CRC8校验码附在信息字段的后面,所以要将信息字段的数左移8位。最后用x8m(x)得到的二进制数对生成多项式g(x)进行模二运算,最终的余数(其二进制数的位数一定比生成多项式g(x)的位数小)就是所要的CRC8校验码。

crc8校验查表法实现方法

/* CRC-8 for Dallas iButton products From Maxim/Dallas AP Note 27 "Understanding and Using Cyclic Redundancy Checks with Dallas Semiconductor iButton Products" The Ap note describes the CRC-8 algorithm used in the iButton products. Their implementation involves a 256 byte CRC table. This algorithm is implemented here. In addition two other algorithms are shown. One uses nibble arrays and the other uses boolean arithmetic. 18JAN03 - T. Scott Dattalo */ /* crc array from the Maxim ApNote */ unsigned char crc_array[256] = { 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff, 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07, 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a, 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,

CRC校验算法

CRC(Cyclic Redundancy Check)循环冗余校验是常用的数据校验方法,讲CRC 算法的文章很多,之所以还要写这篇,是想换一个方法介绍CRC算法,希望能让大家更容易理解CRC算法。 先说说什么是数据校验。数据在传输过程(比如通过网线在两台计算机间传文件)中,由于传输信道的原因,可能会有误码现象(比如说发送数字5但接收方收到的却是6),如何发现误码呢?方法是发送额外的数据让接收方校验是否正确,这就是数据校验。最容易想到的校验方法是和校验,就是将传送的数据(按字节方式)加起来计算出数据的总和,并将总和传给接收方,接收方收到数据后也计算总和,并与收到的总和比较看是否相同。如果传输中出现误码,那么总和一般不会相同,从而知道有误码产生,可以让发送方再发送一遍数据。 CRC校验也是添加额外数据做为校验码,这就是CRC校验码,那么CRC校验码是如何得到的呢? 非常简单,CRC校验码就是将数据除以某个固定的数(比如ANSI-CRC16中,这个数是0x18005),所得到的余数就是CRC校验码。 那这里就有一个问题,我们传送的是一串字节数据,而不是一个数据,怎么将一串数字变成一个数据呢?这也很简单,比如说2个字节B1,B2,那么对应的数就是(B1<<8)+B2;如果是3个字节B1,B2,B3,那么对应的数就是((B1<<16)+(B2<<8)+B3),比如数字是0x01,0x02,0x03,那么对应的数字就是0x10203;依次类推。如果字节数很多,那么对应的数就非常非常大,不过幸好CRC只需要得到余数,而不需要得到商。 从上面介绍的原理我们可以大致知道CRC校验的准确率,在CRC8中出现了误码但没发现的概率是1/256,CRC16的概率是1/65536,而CRC32的概率则是1/2^32,那已经是非常小了,所以一般在数据不多的情况下用CRC16校验就可以了,而在整个文件的校验中一般用CRC32校验。 这里还有个问题,如果被除数比除数小,那么余数就是被除数本身,比如说只要传一个字节,那么它的CRC就是它自己,为避免这种情况,在做除法之前先将它移位,使它大于除数,那么移多少位呢?这就与所选的固定除数有关了,左移位数比除数的位数少1,下面是常用标准中的除数: CRC8:多项式是X8+X5+X4+1,对应的数字是0x131,左移8位 CRC12:多项式是X12+X11+X3+X2+1,对应的数字是0x180D,左移12位 CCITT CRC16:多项式是X16+X12+X5+1,对应的数字是0x11021,左移16位 ANSI CRC16:多项式是X16+X15+X2+1,对应的数字是0x18005,左移16位 CRC32:多项式是 X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1,对应数字是 0x104C11DB7,左移32 因此,在得到字节串对应的数字后,再将数字左移M位(比如ANSI-CRC16是左移16位),就得到了被除数。 好了,现在被除数和除数都有了,那么就要开始做除法求CRC 校验码了。CRC除法的计算过程与我们笔算除法类似,首先是被除数与除数高位对齐后,被除数减去除数,得到了差,除数再与差的最高位对齐,进行减法,然

crc校验算法

CRC 算法原理及C 语言实现   摘 要 本文从理论上推导出CRC算法实现原理,给出三种分别适应不同计算机或微控制器硬件环境的C语言程序。读者更能根据本算法原理,用不同的语言编写出独特风格更加实用的CRC计算程序。  关键词 CRC 算法 C语言  1 引言 循环冗余码CRC检验技术广泛应用于测控及通信领域。CRC计算可以靠专用的硬件来实现,但是对于低成本的微控制器系统,在没有硬件支持下实现CRC检验,关键的问题就是如何通过软件来完成CRC计算,也就是CRC算法的问题。 这里将提供三种算法,它们稍有不同,一种适用于程序空间十分苛刻但CRC计算速度要求不高的微控制器系统,另一种适用于程序空间较大且CRC计算速度要求较高的计算机或微控制器系统,最后一种是适用于程序空间不太大,且CRC计算速度又不可以太慢的微控制器系统。 2 CRC简介 CRC校验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码)r位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端,则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。  16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(既乘以162) 后,再除以一个多项式,最后所得到的余数既是CRC码,如式(2-1)式所示,其中B(X)表示n位的二进制序列数,G(X)为多项式,Q(X)为整数,R(X)是余数(既CRC码)。  ) ()()()(2)(16X G X R X Q X G X B +=? (2-1) 求CRC码所采用模2加减运算法则,既是不带进位和借位的按位加减,这种加减运算实际上就是逻辑上的异或运算,加法和减法等价,乘法和除法运算与普通代数式的乘除法运算是一样,符合同样的规律。生成CRC码的多项式如下,其中CRC-16和CRC-CCITT产生16位的CRC码,而CRC-32则产生的是32位的CRC码。本文不讨论32位的CRC算法,有兴趣的朋友可以根据本文的思路自己去推导计算方法。  CRC-16:(美国二进制同步系统中采用) 1)(21516+++=X X X X G CRC-CCITT:(由欧洲CCITT推荐) 1)(51216+++=X X X X G CRC-32: 81011121622232632)(X X X X X X X X X X G ++++++++= 112457++++++X X X X X 接收方将接收到的二进制序列数(包括信息码和CRC码)除以多项式,如果余数为0,则说明传输中无错误发生,否则说明传输有误,关于其原理这里不再多述。用软件计算CRC码时,接收方可以将接收到的信息码求CRC码,比较结果和接收到的CRC码是否相同。  3 按位计算CRC

CRC 三种检验方法

计算机网络报告 CRC 三种检验方法 CRC 三种检验方法: //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的3种//实现方法进行测试。方法1选用了一种常见的查表方法,类似的还有512字//节、256字等查找表的,至于查找表的生成,这里也略过。 // ---------------- POPULAR POL YNOMIALS ----------------

// CCITT: x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POL YNOMIALS 0x8005 // -------------------------------------------------------------- // CRC16计算方法1:使用2个256长度的校验表 // -------------------------------------------------------------- const BYTE chCRCHTalbe[] = // CRC 高位字节值表{ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; const BYTE chCRCLTalbe[] = // CRC 低位字节值表{ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,

关于CRC码的基本知识

一、CRC码工作原理 1. CRC校验原理 CRC的英文全称为Cyclic Redundancy Check(Code),中文名称为循环冗余校验(码)。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。 CRC计算与普通的除法计算有所不同。普通的除法计算是借位相减的,而CRC计算则是异或运算。任何一个除法运算都需要选取一个除数,在CRC运算中我们称之为poly,而宽度W就是poly最高位的位置。比如poly 1001的W是3,而不是4。注意最高位总是1,当你选定一个宽度,那么你只需要选择低W各位的值。假如我们想计算一个位串的CRC码,并要保证每一位都要被处理,因此我们需要在目标位串后面加上W个0。 CRC校验原理看起来比较复杂,因为大多数书上基本上是以二进制的多项式形式来说明的。其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模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,也无进位,无借位。相当于二进制中的逻辑异或运算。也就是比较后,两者对应位相同则结果为“0”,不同则结果为“1”。如100101除以1110,结果得到商为11,余数为1,如图5-9左图所示。如11×11=101,如图5-9右图所示。 图5-9 “模2除法”和“模2乘法”示例 具体来说,CRC校验原理就是以下几个步骤:

CRC16校验方法

CRC校验算法 CRC校验算法 CRC(Cyclic Redundancy Check)循环冗余校验是常用的数据校验方法,讲CRC算法的文章很多,之所以还要写这篇,是想换一个方法介绍CRC算法,希望能让大家更容易理解CRC算法。 先说说什么是数据校验。数据在传输过程(比如通过网线在两台计算机间传文件)中,由于传输信道的原因,可能会有误码现象(比如说发送数字5但接收方收到的却是6),如何发现误码呢?方法是发送额外的数据让接收方校验是否正确,这就是数据校验。最容易想到的校验方法是和校验,就是将传送的数据(按字节方式)加起来计算出数据的总和,并将总和传给接收方,接收方收到数据后也计算总和,并与收到的总和比较看是否相同。如果传输中出现误码,那么总和一般不会相同,从而知道有误码产生,可以让发送方再发送一遍数据。 CRC校验也是添加额外数据做为校验码,这就是CRC校验码,那么CRC校验码是如何得到的呢?非常简单,CRC校验码就是将数据除以某个固定的数(比如ANSI-CRC16中,这个数是0x18005),所得到的余数就是CRC校验码。 那这里就有一个问题,我们传送的是一串字节数据,而不是一个数据,怎么将一串数字变成一个数据呢?这也很简单,比如说2个字节B1,B2,那么对应的数就是(B1<<8)+B2;如果是3个字节B1,B2,B3,那么对应的数就是((B1<<16)+(B2<<8)+B3),比如数字是0x01,0x02,0x03,那么对应的数字就是0x10203;依次类推。如果字节数很多,那么对应的数就非常非常大,不过幸好CRC只需要得到余数,而不需要得到商。 从上面介绍的原理我们可以大致知道CRC校验的准确率,在CRC8中出现了误码但没发现的概率是1/256,CRC16的概率是1/65536,而CRC32的概率则是1/2^32,那已经是非常小了,所以一般在数据不多的情况下用CRC16校验就可以了,而在整个文件的校验中一般用CRC32校验。 这里还有个问题,如果被除数比除数小,那么余数就是被除数本身,比如说只要传一个字节,那么它的CRC就是它自己,为避免这种情况,在做除法之前先将它移位,使它大于除数,那么移多少位呢?这就与所选的固定除数有关了,左移位数比除数的位数少1,下面是常用标准中的除数:CRC8:多项式是X8+X5+X4+1,对应的数字是0x131,左移8位 CRC12:多项式是X12+X11+X3+X2+1,对应的数字是0x180D,左移12位 CCITT CRC16:多项式是X16+X12+X5+1,对应的数字是0x11021,左移16位 ANSI CRC16:多项式是X16+X15+X2+1,对应的数字是0x18005,左移16位 CRC32:多项式是X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1,对应数字是0x104C11DB7,左移32位。

相关主题
相关文档
最新文档