CR校验——不同的生成多项式对应不同的表
- 格式:doc
- 大小:57.00 KB
- 文档页数:11
标准CRC生成多项式如下表:名称生成多项式简记式* 标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8 x8+x6+x4+x3+x2+x1 0x5ECRC-12 x12+x11+x3+x+1 80FCRC-16 x16+x15+x2+1 8005 IBM SDLCCRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42,PPP-FCSCRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP生成多项式的最高位固定的1,故在简记式中忽略最高位1了,如0x1021实际是0x11021。
I、基本算法(人工笔算):以CRC16-CCITT为例进行说明,CRC校验码为16位,生成多项式17位。
假如数据流为4字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0];数据流左移16位,相当于扩大256×256倍,再除以生成多项式0x11021,做不借位的除法运算(相当于按位异或),所得的余数就是CRC校验码。
发送时的数据流为6字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0]、CRC[1]、CRC[0];II、计算机算法1(比特型算法):1)将扩大后的数据流(6字节)高16位(BYTE[3]、BYTE[2])放入一个长度为16的寄存器;2)如果寄存器的首位为1,将寄存器左移1位(寄存器的最低位从下一个字节获得),再与生成多项式的简记式异或;否则仅将寄存器左移1位(寄存器的最低位从下一个字节获得);3)重复第2步,直到数据流(6字节)全部移入寄存器;4)寄存器中的值则为CRC校验码CRC[1]、CRC[0]。
crc校验码的生成方法Cyclic Redundancy Check(CRC)校验码是一种在数字通信中检测数据错误的方法。
CRC校验码的生成是通过对数据进行一系列数学运算(异或运算)得到的。
生成CRC校验码的过程包括以下步骤:1. 选择CRC多项式:CRC多项式是CRC算法中的关键部分,它决定了校验码生成的方式。
不同的CRC多项式用于不同的应用场景。
常见的CRC多项式包括CRC-16、CRC-32等。
每种CRC多项式都由一个二进制数表示。
2. 初始化:将CRC寄存器初始化为一个特定的值,通常为全0。
这个值的选择可能与CRC 多项式有关。
3. 按位处理数据:将待校验的数据按位处理,从最高位到最低位。
对于每一位,执行以下操作:-将CRC寄存器的高位与当前数据位进行异或操作。
-将CRC寄存器左移一位。
4. 处理完所有数据位:经过上述处理后,CRC寄存器中存储的就是生成的CRC校验码。
5. 最终异或:在得到CRC校验码后,通常还需要将其与一个预定的值进行最终的异或操作。
这个预定的值可能是一些预定义的常数,具体取决于CRC的实现。
下面是一个简化的伪代码示例,说明CRC校验码的生成过程:```plaintextfunction generateCRC(data):CRC_POLYNOMIAL = 0xA001 # 16-bit CRC polynomial, for exampleCRC_REGISTER = 0xFFFF # Initial value of CRC registerfor each bit in data:CRC_REGISTER = CRC_REGISTER XOR (bit << 8)for i from 0 to 7:if (CRC_REGISTER AND 0x8000) != 0:CRC_REGISTER = (CRC_REGISTER << 1) XOR CRC_POLYNOMIALelse:CRC_REGISTER = CRC_REGISTER << 1CRC_RESULT = CRC_REGISTER XOR 0xFFFF # Final XOR operationreturn CRC_RESULT```在实际应用中,CRC校验码的生成方法可能会因CRC多项式的不同而有所变化。
CRC校验原理及步骤CRC(Cyclic Redundancy Check)校验是一种常用的错误检测方法,用于验证数据传输过程中是否存在错误。
CRC校验采用生成多项式对数据进行计算,从而生成一个固定长度的冗余校验码,将该校验码附加在数据后面进行传输,接收方利用同样的生成多项式对接收到的数据进行计算,并与接收到的校验码进行比较,如果校验码一致,则认为数据传输没有错误;如果校验码不一致,则认为数据传输存在错误。
1.选择生成多项式:在进行CRC校验前,需要选择一个生成多项式。
常用的生成多项式有:CRC-8,CRC-16,CRC-32等。
根据实际情况选择不同的生成多项式。
2.数据填充:在数据的末尾添加一组"0",长度等于生成多项式的次数加1、例如,如果选择的生成多项式为CRC-8,则在数据末尾填充一组"0",长度为9;如果选择的生成多项式为CRC-16,则在数据末尾填充一组"0",长度为173.生成校验码:利用生成多项式对填充后的数据进行除法运算,计算余数。
余数即为校验码。
通常,余数的位数为生成多项式的次数。
4.将校验码添加到数据中:将生成的校验码添加到数据末尾,并进行传输。
5.接收方计算校验码:接收方接收到数据后,利用接收到的数据和相同的生成多项式进行除法运算,计算余数。
6.比较校验码:接收方得到余数后,将其与接收到的校验码进行比较。
如果两者一致,则认为数据传输没有错误;如果两者不一致,则认为数据传输存在错误。
CRC校验的原理是利用多项式除法运算,将数据作为一个伪多项式进行计算,并得到一个余数。
由于多项式的特性,如果在数据传输过程中出现了错误,那么接收方计算得到的余数一定与发送方生成的校验码不一致。
通过比较余数和校验码,接收方可以判断数据是否传输正确。
1.简单高效:CRC校验算法计算速度快,适用于高速数据传输。
2.安全性高:CRC校验算法能够高效地检测出多种错误,包括单比特错误、双比特错误等。
CRC校验实现的过程说明
1.确定生成多项式
在CRC校验中,首先需要确定生成多项式。
生成多项式是一个二进制数,最高位和最低位分别为1,中间可以是任意二进制数。
生成多项式的
不同取值对应着不同的CRC校验算法。
常用的生成多项式有CRC-8、CRC-
16和CRC-32等。
2.初始化寄存器
3.数据处理
将待校验的数据按照二进制方式表示,并将每一位依次输入到计算寄
存器。
这样,整个待校验的数据就可以被寄存器包含。
4.CRC计算
通过移位异或的方式进行CRC计算。
移位是将寄存器的所有位向左移
一位,同时将输入位移入最低位。
异或是对于多项式中为1的位,如果寄
存器的对应位为1,则结果为0,否则结果为1、通过多次移位异或操作,直到所有位都处理完毕。
5.输出校验值
当所有位都处理完毕后,寄存器中的值即为校验值。
这个校验值可以
附加在数据传输的末尾。
接收方在接收到数据后,进行相同的校验操作,
如果计算出的校验值与接收到的校验值相同,说明传输过程没有发生错误。
然而,CRC校验也有一些限制。
它只能检测错误的存在,不能提供错
误的位置信息。
此外,CRC校验是一种线性校验方法,无法检测出所有的
双位错误。
综上所述,CRC校验实现的过程是通过生成多项式、初始化寄存器、数据处理、CRC计算和输出校验值来完成的。
它是一种简单、快速和可靠的检错技术,在数据传输中得到广泛应用。
crc16校验查表法原理CRC(Cyclic Redundancy Check)是一种常用的数据校验方法,广泛应用于数据通信和存储中,以确保数据的完整性和准确性。
CRC校验可以通过查表法来实现,本文将介绍CRC16校验的查表法原理。
在CRC校验中,发送方和接收方通过一系列的计算操作来生成和校验校验码。
其中,CRC16是一种16位的循环冗余校验码,可以检测出多达2个比特的错误。
CRC16校验的查表法是一种基于查表的快速计算方法,通过预先构建一个256个元素的查表来加速校验码的计算。
我们需要准备一个256个元素的查表,每个元素都是一个16位的值。
这个查表可以通过生成多项式来计算得到,CRC16通常使用的是0x8005或0x1021这两个生成多项式。
通过对这两个多项式进行反转和左移操作,我们可以得到一个256个元素的查表。
接下来,我们需要将待校验的数据按照字节进行拆分,并将每个字节和当前的校验码进行异或运算。
异或运算是一种位运算,其运算规则是两个数对应位相同则结果为0,不同则结果为1。
通过不断地进行异或运算,将每个字节和当前的校验码进行异或,最终得到一个16位的校验码。
然后,我们可以通过查表的方式来加速校验码的计算。
对于每个字节,我们可以将它作为查表的索引,查表的结果就是一个16位的值。
然后,我们将这个值和当前的校验码进行异或运算,得到一个新的校验码。
通过不断地查表和异或运算,最终得到的校验码就是CRC16校验码。
CRC16校验的查表法相比于其他计算方法具有高效和简洁的特点。
通过预先构建查表,可以大大减少计算的时间和复杂度。
同时,查表法还可以方便地用于硬件电路的设计和实现,提高系统的性能和可扩展性。
需要注意的是,CRC16校验的查表法并不是唯一的实现方式,还可以使用其他方法来计算校验码。
而且,在实际应用中,不同的通信协议和设备可能会采用不同的CRC算法和生成多项式。
CRC16校验的查表法是一种基于查表的快速计算方法,通过预先构建一个256个元素的查表,可以加速CRC16校验码的计算。
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位的余数。
CRC(循环冗余校验)是一种用于检测数据传输错误的算法。
在CRC中,有一个称为“逆序表格”的概念,它是一种预先计算好的表,用于快速计算CRC校验码。
这个表格包含了固定长度的二进制串对应的CRC值,对于一个给定的生成多项式,可以生成一个唯一的逆序表格。
通过使用这个表,可以在常数时间内查找对应的CRC值,从而提高了计算效率。
逆序表格的生成方法是基于多项式的逆元和模运算的性质。
具体来说,对于一个给定的生成多项式,首先将它转换为二进制形式,然后通过遍历二进制串的所有可能情况来生成表格。
对于每个二进制串,计算其CRC值,并将结果存储在表格中。
最终得到的表格就是逆序表格。
使用逆序表格进行CRC计算时,首先将要校验的数据转换为二进制串,然后通过查找逆序表格找到对应的CRC值。
如果计算得到的CRC值与预存的CRC值相等,则说明数据传输无误;否则,说明数据传输过程中出现了错误。
需要注意的是,逆序表格的生成和存储都需要一定的时间和空间资源。
因此,在实际应用中,需要根据具体情况选择合适的生成多项式和存储方式,以实现高效、准确的CRC校验。
crc检验流程(二)CRC检验流程什么是CRC检验CRC(Cyclic Redundancy Check)是一种常用的数据校验方法,用于验证数据在传输过程中是否发生了错误。
它通过对数据进行计算得到校验码,并将校验码附加到数据中进行传输,接收方根据接收到的数据和校验码重新计算校验码来验证数据的完整性。
CRC检验流程概述CRC检验流程主要包括以下几个步骤:1.选择生成多项式:在进行CRC校验前,首先需要选择一个合适的生成多项式。
生成多项式的选择有很多标准,常用的包括CRC-8、CRC-16、CRC-32等,根据需要选择合适的生成多项式。
2.生成校验码表:根据选定的生成多项式,生成一个校验码表,用于在CRC计算过程中查找校验码。
生成校验码表的方法如下:–初始化一个全为0的数组,长度为2的生成多项式的次数次方。
–从0到256遍历每一个可能的8位数据,对每个数据进行一系列操作,根据生成多项式进行逐位计算。
–将计算得到的校验码存储在对应的数组位置上。
3.计算CRC校验码:待发送的数据经过一系列位运算,将生成的校验码附加在数据后面,形成待传输的数据包。
CRC计算的过程如下:–将待发送的数据和初始化的CRC值进行异或操作。
–将每一位数据进行移位操作,从高位到低位进行处理。
–如果移位后得到的最高位为1,则对该值和生成多项式进行异或操作。
–重复以上操作,直到将所有的数据位都处理完毕。
–最终得到的CRC值就是校验码。
4.发送数据包:将包含校验码的数据包发送给接收方。
5.接收方校验:接收方通过相同的CRC计算过程,重新计算接收到的数据的CRC值,并将计算得到的CRC值与接收到的CRC值进行比较。
如果计算得到的CRC值与接收到的CRC值一致,则说明数据在传输过程中没有发生错误;反之,说明数据存在错误。
CRC检验流程总结通过选择合适的生成多项式,生成校验码表,以及计算和校验CRC值的过程,CRC检验可以有效地验证数据的完整性,提高数据传输的可靠性。
crc校验查表法原理CRC(Cyclic Redundancy Check)校验是一种常用的数据传输错误检测方法,广泛应用于计算机网络、通信等领域。
CRC校验的查表法原理是其中一种实现方式,通过查表的方式来进行校验计算,下面将详细介绍这种方法的原理和应用。
1. CRC校验的基本原理CRC校验是一种基于多项式除法的校验方法。
在CRC校验过程中,发送方和接收方约定一个生成多项式(Generator Polynomial),通常记作G(x)。
发送方在发送数据之前,先计算待发送数据的CRC校验值,并将其附加到数据末尾,形成一个完整的帧。
接收方同样计算接收到数据的CRC校验值,并与接收到的CRC校验值进行比较,如果两者相等,则数据传输没有出现错误。
2. 查表法原理查表法是实现CRC校验的一种高效方法。
其基本原理是将CRC校验过程中的除法运算转化为查表操作,从而提高计算效率。
具体步骤如下:(1)生成查表表格:根据生成多项式G(x)的阶数,生成一个2^m 大小的查表表格,其中m为生成多项式的阶数。
(2)数据处理:将待发送的数据按照二进制形式表示,并在数据末尾添加n个0,其中n为生成多项式的阶数。
(3)查表运算:从数据的最高位开始,每次取m位数据,并将其作为查表表格的索引,找到对应的查表值。
然后将查表值与当前数据进行异或运算,并将结果作为下一次计算的数据。
(4)重复上述操作,直到处理完所有数据位。
(5)得到CRC校验值:经过上述计算后,最后剩下的数据即为CRC 校验值,将其附加到原始数据末尾,形成一个完整的帧。
3. 查表法的优势相比于其他计算方法,查表法具有以下几个优势:(1)高效性:通过查表的方式,可以大大提高CRC校验的计算效率,尤其是对于大数据量的情况,查表法比较快速。
(2)易于实现:查表法的实现相对简单,只需要生成查表表格,并根据表格进行查表运算即可。
(3)节省存储空间:通过查表的方式,可以将除法运算转化为查表操作,从而避免了除法运算需要的存储空间。
crc 查表法原理CRC(Cyclic Redundancy Check)是一种数据校验算法,通过对数据进行多项式除法运算来计算校验值。
而CRC查表法是一种优化的实现方式,通过事先计算并存储CRC校验表,可以在实际计算时提高效率。
CRC查表法的原理是将每一个可能的输入值都预先计算出其对应的校验值,并存储在一个查表表格中。
在实际计算时,只需要将输入数据作为表格的索引,即可直接查表得到对应的校验值,而无需执行多项式除法运算。
具体实现过程如下:1. 初始化CRC校验表格:根据所使用的CRC算法,确定校验表格的大小。
通常来说,CRC校验表格的大小为256个元素(对应8位输入数据),每个元素的大小为CRC校验值的位数(比特数)。
2. 计算CRC校验表格:对于每一个可能的输入值,按照CRC算法的定义进行计算,并存储在对应的表格位置上。
3. 输入数据的校验:将输入数据按照CRC算法的定义进行计算。
对于每一个输入数据的字节,将其作为表格的索引,查找对应的校验值,并与之前的校验结果进行异或运算。
最后得到的校验结果即为最终的CRC校验值。
CRC查表法的优点在于其计算速度较快。
由于查表操作只需要进行简单的内存读取,而不需要执行复杂的除法运算,因此能够大幅提高计算效率。
尤其是在对大量数据进行CRC校验时,使用查表法可以极大地提高处理速度。
CRC查表法还具有可扩展性。
由于查表法的实现方式与所使用的CRC 算法无关,只需要根据具体的CRC算法生成对应的校验表格即可。
因此,只要校验表格的生成过程正确,就可以适用于不同的CRC算法,无需修改算法本身。
需要注意的是,CRC查表法的缺点是占用较大的内存空间。
由于需要事先生成完整的校验表格,所以对于CRC校验值较长的情况,表格的大小会成倍增加,从而占用更多的内存。
因此,在内存资源有限的嵌入式系统中,可能需要权衡计算速度和内存占用,选择合适的实现方式。
CRC查表法是一种优化的CRC校验算法实现方式,通过事先计算并存储CRC校验表格,可以在实际计算时提高效率。
标题:CRC16余式查表法对应的多项式公式目录1. 什么是CRC16余式查表法2. CRC16余式查表法的原理3. CRC16余式查表法所对应的多项式公式4. CRC16余式查表法的应用5. 结论正文1. 什么是CRC16余式查表法CRC(Cyclic Redundancy Check)循环冗余校验是一种常用的数据校验方法,用于检测数据传输或存储过程中出现的错误。
CRC16是一种16位的循环冗余校验算法,它通过对待校验数据进行预先约定的除法运算来生成校验码。
在实际应用中,可以使用不同的生成多项式来对数据进行校验,其中CRC16余式查表法就是一种常见的实现方式。
2. CRC16余式查表法的原理CRC16余式查表法的核心思想是利用一个预先生成的查表来快速计算数据的校验码。
具体来说,它首先需要一个预先生成的256个16位二进制数的查表,对于每个8位的输入数据字节,它将根据这个字节的值从查表中找到对应的16位余式,并将其与之前的余式进行异或计算,得到新的余式。
通过重复这个过程直到所有数据字节都被处理完毕,最终生成的余式就是数据的CRC16校验码。
3. CRC16余式查表法所对应的多项式公式CRC16余式查表法对应的多项式公式可以用如下形式表示:G(x) = x^16 + x^15 + x^2 + 1其中,G(x)是一个16位的多项式,它对应了CRC16的生成多项式。
在实际计算中,可以直接利用这个多项式来进行CRC16的计算,而不需要每次都对16位的二进制数进行除法运算。
这样就大大提高了计算的效率,特别是对于嵌入式系统等资源受限的环境来说,CRC16余式查表法提供了一种高效的数据校验算法。
4. CRC16余式查表法的应用CRC16余式查表法广泛应用于数据通信、存储和传输的领域。
由于它计算效率高、实现简单且不依赖除法运算,因此被广泛应用在各种需要数据校验的场景中,如网络通信协议(如Modbus、Profibus等)、文件传输(如ZMODEM协议、XMODEM协议等)以及存储介质(如磁盘、闪存等)等。
crc的生成多项式CRC的生成多项式CRC(Cyclic Redundancy Check)是一种常用的校验码,它可以检测或纠正数据传输过程中的错误。
在CRC算法中,生成多项式起着至关重要的作用,它决定了CRC校验码的计算方式和校验能力。
本文将详细探讨CRC的生成多项式及其相关概念。
一、生成多项式的定义与作用生成多项式是CRC算法中的关键部分,它是一个二进制数,表示为一个多项式。
生成多项式的系数决定了CRC校验码的计算方式,不同的生成多项式会产生不同的CRC校验码。
生成多项式相当于给待发送的数据添加了一个附加信息,通过对数据进行多项式除法运算,最后得到的余数作为CRC校验码。
接收端在收到数据后,同样进行多项式除法运算,如果余数为0,则数据传输没有错误;如果余数不为0,则数据传输存在错误。
二、生成多项式的表示方法1.系数表示法:生成多项式的系数可以用一串二进制数表示,长度为n+1,其中n为生成多项式的次数,最高次方对应的系数为1,其余次方的系数为0。
2.多项式表示法:生成多项式可以用一个多项式表示,其中多项式的次数为n,而系数为1的次数对应的指数为1,其余指数为0。
例如,生成多项式CRC-16可以表示为:"x^16 + x^15 + x^2 + 1",或用系数形式表示为:"10000000000000001"。
三、CRC的选择与设计在实际应用中,选择合适的生成多项式对CRC算法的性能和可靠性有着重要的影响。
一个好的生成多项式需要满足以下几个要求:1.较高的错误检测能力:生成多项式能够最大限度地检测出传输过程中的错误,保障数据的可靠性。
2.较低的冲突率:生成多项式应尽量避免不同数据产生相同的CRC校验码,以减小误判的概率。
3.多项式次数的选取:多项式的次数应选择适中,既能保证较高的错误检测能力,又能满足运算效率的要求。
四、应用实例CRC算法广泛应用于计算机网络、存储系统、数据传输等领域。
介绍两种简单实用的信道编码——CRC校验和汉明码1)关于编码的基础知识在信息的传输过程中,为了达到更高效、更低误码的目的,不可避免地要在发送端进行编码,在接收端进行解码。
通常,编码可以分为信源编码和信道编码,具体的区分可以见下图:信源编码是用于压缩数据用的;信道编码是用于增加检错、纠错信息,抵抗传输误码的。
例如:奇偶校验、和校验,就是两种最简单的信道编码,在接收端,如果发现校验位/校验字节不对,就可以知道传输中出现了误码,这就是信道编码的作用。
当然,复杂一些的信道编码不只能发现传输错误,还能在一定程度上纠正传输错误。
本文中要讲的,CRC校验码和汉明码(hamming code),都属于信道编码,它们实现起来简单,效果却非常好。
常见的奇偶校验、和校验只能检出部分误码,能力有限,而CRC 校验码可以检出多个bit位的传输错误,有文献表明,CRC16能100%检出:单个位误码、双位误码、奇数个误码、短于16bit的误码,能以99.99%以上的概率检出其他突发性误码。
汉明码与前面几种只能查错的编码不同,它甚至还可以纠正单个bit位的传输错误。
2)CRC校验码首先来了解一下CRC校验码的原理。
假设我们有一串原始信息bit流要传输,从高位到低位依次为:序列1=11001100;我们再选择一个用于生成CRC校验码的序列,假设为:序列2=100000111,总长度为k=9;我们暂时称其为“生成多项式”;然后,我们在原始信息序列1后面增加(k-1)个0,将其和生成多项式序列2进行“模二除“(计算时不进位也不借位,二进制除法,相当于按位异或),计算过程如下:最后得到一个k-1位长度的余数(位数不够的把前面的0也算上),这个余数就是计算得到的CRC校验。
把这个余数替换到原始信息序列1后面,得到新的序列:1100110001101010,因为新的序列在末尾加上了“余数”,所以这个新的序列可以“整除”生成多项式序列2。
这样,我们只要在发送端计算出CRC校验,附加到原始信息的末尾一起发送,在接收端看能否整除,就能知道传输过程中有没有误码。
CRC校验算法详解循环冗余校验(Cyclic Redundancy Check,CRC)是一种常用的错误校验算法,主要用于数据传输过程中的差错检测。
它将数据视为二进制数,通过生成多项式与数据进行异或运算,最后产生一个余数,将该余数作为校验码附加在数据末尾,接收方通过相同的生成多项式进行校验,如果余数为0,则认为数据传输无误。
CRC校验算法的基本原理是:通过生成多项式对整个数据进行模2除法运算,并得到一个余数作为校验码。
在数据传输过程中,发送方将原始数据和校验码一起发送给接收方,接收方利用相同的生成多项式对整个数据进行除法运算,并检查余数是否为0,来判断数据传输是否正确。
1.确定生成多项式:CRC校验算法中最重要的是生成多项式,它决定了校验能力的大小。
生成多项式通常在最高位和最低位都为1,其他位数也应该尽量选择为1、常用的生成多项式有CRC-8、CRC-16、CRC-32等,每种生成多项式的校验能力不同。
2.将生成多项式转换为二进制数:将生成多项式转换为二进制数表示,用多项式系数的二进制表示法来表示生成多项式。
3.将待发送的数据与校验码进行拼接:在发送数据的最后面添加足够位数的0,等于生成多项式次数减1,将生成多项式次方数减1的二进制表示添加到待发送的数据末尾。
4.进行模2除法运算:将待发送的数据与生成多项式进行模2除法运算,将得到的余数作为校验码。
5.发送数据与校验码:将原始数据与校验码一起发送给接收方,接收方接收到数据后利用相同的生成多项式进行除法运算。
6.检验余数是否为0:接收方进行除法运算后,检查得到的余数是否为0,如果余数为0,则认为数据传输无误;如果余数不为0,则认为数据传输存在错误。
CRC校验算法的优点是简单且高效,能够检测多位错误,且校验码的长度可以根据生成多项式的次方数来确定,可以根据不同的数据传输要求进行调整。
缺点则是无法纠正错误,只能检测错误的存在,需要额外的处理机制来进行纠正。
给定生成多项式,计算比特序列的crc校验码生成多项式CRC校验码是现代通信领域中广泛采用的错误检测技术。
本文将介绍给定生成多项式,如何计算比特序列的CRC校验码。
一、什么是生成多项式生成多项式是CRC校验算法中的一个重要参数,它是一个不同于0和1的二进制多项式,它决定了CRC计算的方式和最终生成的校验码。
例如,一个生成多项式为x^3 + x^2 + 1,其二进制表示为1011。
这个多项式包含了三个项,其中最高项的系数为1。
生成多项式的位数决定了CRC校验码的位数,本例中的生成多项式为3位,生成的CRC码也是3位。
二、CRC校验过程现在我们来看一下如何计算给定比特序列的CRC校验码。
CRC校验过程可以分为以下几个步骤:1.初始化寄存器,将寄存器设为全0。
2.将比特序列一个一个的输入寄存器中,并按照生成多项式进行除法运算,将余数保留在寄存器中。
3.当所有的数据位都被计算完后,在寄存器中剩余的余数即为CRC码。
4.最后将CRC码附加到原始数据中进行传输,接收方使用相同的生成多项式和校验码来进行校验,如果计算出的CRC值与接收到的CRC 值不一致,则认为数据出现了错误。
三、示例以下是一个示例,计算给定数据11010011101100的CRC校验码。
1.首先确定生成多项式为x^3 + x^2 + 1,其二进制表示为1011,所以我们需要在输入数据的末尾附加三个零,这是处理CRC校验时的一种约定。
2.将生成多项式左移一位,即变为10110,这个多项式的位数为5,所以剩下的数据也应附加5个零,即变为110100111011000000。
现在我们可以开始计算CRC校验码了。
初始化寄存器为全0:0000输入第一个比特1:0001按照行程多项式1011进行除法运算:00011011 <-- 生成多项式0000-----0001此时寄存器中的余数为0001。
输入下一个比特1:0011将上一步计算出来的余数左移一位,变成0010,然后将新的比特1加入到最低位上:00100011----0001按照生成多项式1011进行除法运算:00011011 <-- 生成多项式0000-----0001此时寄存器中的余数还是0001。
标准CRC生成多项式如下表:名称生成多项式简记式* 标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8 x8+x6+x4+x3+x2+x1 0x5ECRC-12 x12+x11+x3+x+1 80FCRC-16 x16+x15+x2+1 8005 IBM SDLCCRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42,PPP-FCSCRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP生成多项式的最高位固定的1,故在简记式中忽略最高位1了,如0x1021实际是0x11021。
I、基本算法(人工笔算):以CRC16-CCITT为例进行说明,CRC校验码为16位,生成多项式17位。
假如数据流为4字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0];数据流左移16位,相当于扩大256×256倍,再除以生成多项式0x11021,做不借位的除法运算(相当于按位异或),所得的余数就是CRC校验码。
发送时的数据流为6字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0]、CRC[1]、CRC[0];II、计算机算法1(比特型算法):1)将扩大后的数据流(6字节)高16位(BYTE[3]、BYTE[2])放入一个长度为16的寄存器;2)如果寄存器的首位为1,将寄存器左移1位(寄存器的最低位从下一个字节获得),再与生成多项式的简记式异或;否则仅将寄存器左移1位(寄存器的最低位从下一个字节获得);3)重复第2步,直到数据流(6字节)全部移入寄存器;4)寄存器中的值则为CRC校验码CRC[1]、CRC[0]。
III、计算机算法2(字节型算法):256^n表示256的n次方把按字节排列的数据流表示成数学多项式,设数据流为BYTE[n]BYTE[n-1]BYTE[n-2]、、、BYTE[1]BYTE[0],表示成数学表达式为BYTE[n]×256^n+BYTE[n-1]×256^(n-1)+...+BYTE[1]*256+BYTE[0],在这里+表示为异或运算。
设生成多项式为G17(17bit),CRC码为CRC16。
则,CRC16=(BYTE[n]×256^n+BYTE[n-1]×256^(n-1)+...+BYTE[1]×256+BYTE[0])×256^2/G17,即数据流左移16位,再除以生成多项式G17。
先变换BYTE[n-1]、BYTE[n-1]扩大后的形式,CRC16=BYTE[n]×256^n×256^2/G17+BYTE[n-1]×256^(n-1)×256^2/G17+...+BYTE[1]×256×256^2/G17 +BYTE[0]×256^2/G17=(Z[n]+Y[n]/G17)×256^n+BYTE[n-1]×256^(n-1)×256^2/G17+...+BYTE[1]×256×256^2/G17+BY TE[0]×256^2/G17=Z[n]×256^n+{Y[n]×256/G17+BYTE[n-1]×256^2/G17}×256^(n-1)+...+BYTE[1]×256×256^2/G1 7+BYTE[0]×256^2/G17=Z[n]×256^n+{(YH8[n]×256+YHL[n])×256/G17+BYTE[n-1]×256^2/G17}×256^(n-1)+...+BYTE [1]×256×256^2/G17+BYTE[0]×256^2/G17=Z[n]×256^n+{YHL[n]×256/G17+(YH8[n]+BYTE[n-1])×256^2/G17}×256^(n-1)+...+BYTE[1]×2 56×256^2/G17+BYTE[0]×256^2/G17这样就推导出,BYTE[n-1]字节的CRC校验码为{YHL[n]×256/G17+(YH8[n]+BYTE[n-1])×256^2/G17},即上一字节CRC校验码Y[n]的高8位(YH8[n])与本字节BYTE[n-1]异或,该结果单独计算CRC校验码(即单字节的16位CRC校验码,对单字节可建立表格,预先生成对应的16位CRC校验码),所得的CRC校验码与上一字节CRC校验码Y[n]的低8位(YL8[n])乘以256(即左移8位)异或。
然后依次逐个字节求出CRC,直到BYTE[0]。
字节型算法的一般描述为:本字节的CRC码,等于上一字节CRC码的低8位左移8位,与上一字节CRC右移8位同本字节异或后所得的CRC码异或。
字节型算法如下:1)CRC寄存器组初始化为全"0"(0x0000)。
(注意:CRC寄存器组初始化全为1时,最后CRC应取反。
)2)CRC寄存器组向左移8位,并保存到CRC寄存器组。
3)原CRC寄存器组高8位(右移8位)与数据字节进行异或运算,得出一个指向值表的索引。
4)索引所指的表值与CRC寄存器组做异或运算。
5)数据指针加1,如果数据没有全部处理完,则重复步骤2)。
6)得出CRC。
unsigned short GetCrc_16(unsigned char * pData, int nLength)//函数功能:计算数据流* pData的16位CRC校验码,数据流长度为nLength{unsigned short cRc_16 = 0x0000; // 初始化while(nLength>0){cRc_16 = (cRc_16 << 8) ^ cRctable_16[((cRc_16>>8) ^ *pData) & 0xff]; //cRctable_16表由函数mK_cRctable生成nLength--;pData++;}return cRc_16;}void mK_cRctable(unsigned short gEnpoly)//函数功能:生成0-255对应的16CRC校验码,其实就是计算机算法1(比特型算法)//gEnpoly为生成多项式//注意,低位先传送时,生成多项式应反转(低位与高位互换)。
如CRC16-CCITT为0x1021,反转后为0x8408{unsigned short cRc_16=0;unsigned short i,j,k;for(i=0,k=0;i<256;i++,k++){cRc_16 = i<<8;for(j=8;j>0;j--){if(cRc_16&0x8000) //反转时cRc_16&0x0001cRc_16=(cRc_16<<=1)^gEnpoly; //反转时cRc_16=(cRc_16>>=1)^gEnpolyelsecRc_16<<=1; //反转时cRc_16>>=1}cRctable_16[k] = cRc_16;}}这几天研究了一下CRC算法,碰到了一些问题,研究了一下,小有心得。
CRC算法是在通讯领域广泛采用的校验算法。
原理我就不说了,这里说一下简单的程序实现。
以下均采用CRC多项式为0x1021即:g(x) = x16+x12+x5+x0;CRC的基本原理就不说了,那个搜一下就有了。
最基本的算法应该是按位计算了,这个方法可以适用于所有长度的数据校验,最为灵活,但由于是按位计算,其效率并不是最优,只适用于对速度不敏感的场合。
基本的算法如下:unsigned short do_crc_16(unsigned char *message, unsigned int len) {int i, j;unsigned short crc_reg = 0;unsigned short current;for (i = 0; i < len; i++){current = message[i] << 8;for (j = 0; j < 8; j++){if ((short)(crc_reg ^ current) < 0)crc_reg = (crc_reg << 1) ^ 0x1021;elsecrc_reg <<= 1;current <<= 1;}}return crc_reg;}以是方法可以计算出任意长度数据的校验。
但速度慢。
下面介绍一种按字节计算的方法:按字节校验是每次计算8位数据,多是基于查表的算法,首先要准备一个表,一共256项。
unsigned int crc_ta[256]={ /* CRC余式表 */0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};unsigned short do_crc_table(unsigned char *ptr,int len){unsigned short int crc;unsigned char da;crc=0;while(len--!=0){da=(unsigned short)crc>>8; /* 以8位二进制数的形式暂存CRC的高8位 */crc<<=8; /* 左移8位,相当于CRC的低8位乘以 */ crc^=crc_ta[da^*ptr]; /* 高8位和当前字节相加后再查表求CRC ,再加上以前的CRC */ptr++;}return(crc);}以上算法实现了按字节进行计算校验值。