标准CRC生成多项式如下表:

合集下载

CR校验——不同的生成多项式对应不同的表

CR校验——不同的生成多项式对应不同的表

标准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-16标准规定的生成多项式为g(x)

crc-16标准规定的生成多项式为g(x)

crc-16标准规定的生成多项式为g(x),介绍CRC-16
CRC-16 (Cyclic Redundancy Check)是一种数据校验技术,是在传输、存储数据时为了确保数据正确性而制定的一种标准。

CRC-16 算法能够鉴别接收到的数据是否被妥善地传输,从而让传输者和接收者都能够确保他们正在使用的数据是没有被篡改的。

CRC-16 标准的生成多项式为g(x),它被定义为:g(x)=x 16+x 15+x 2+1。

这里的x表示无符号位,而1则为最高位。

CRC-16 标准使用多项式来对数据进行校验,根据每一位数据得到的校验和会作为下一个位发送。

如果收到的CRC校验和与原CRC码不同,则说明数据在传输过程中发生了错误,这时就需要重新发送数据。

在实际应用中,CRC-16 一般由接收者在接收到数据时先进行CRC-16 校验码的计算,将计算结果和原来传输的校验码进行对比,如果不一致则说明数据在传输过程中出现了错误,需要重新进行传输。

同时,CRC-16 的计算过程也是可以任意算法实现的,不一定要使用指定的多项式g(x)。

因为CRC-16校验算法的计算过程及其结果计算都具有较轻松的容错能力,所以CRC-16 已经成为一种比较主流的数据可靠性保证方案,广泛用于电脑系统、数字通信、EN877标准等领域。

总结起来,CRC-16 通过校验算法和生成多项式g(x)使得发送者和接收者可以确保正在使用的数据是安全的,同时又能够检测出数据传输的可靠性,对保证数据的完整性和安全性具有重要的作用。

最详细易懂的CRC-16校验原理(附源程序)

最详细易懂的CRC-16校验原理(附源程序)

最详细易懂的CRC-16校验原理(附源程序)1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。

2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘和’取值的多项式一一对应。

例如:代码对应的多项式为X6+X4+X2+X+1,而多项式为X5+X3+X2+X+1对应的代码101111 o标准CRC生成多项式如下表:名称生成多项式简记式*标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8x8+x6+x4+x3+x2+x10x5ECRC-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 SCTP3、CRC-16校验码的使用:现选择最常用的CRC-16校验,说明它的使用方法。

根据Modbus协议,常规485通讯的信息发送形式如下:地址功能码数据信息校验码1byte 1byte nbyte 2byteCRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。

例如:信息字段代码为:1011001,校验字段为:1010。

发送方:发出的传输字段为:1 0 1 1 0 0 1 1 0 10信息字段校验字段接收方:使用相同的计算方法计算出信息字段的校验码,对比接收到的实际校验码,如果相等及信息正确,不相等则信息错误;或者将接受到的所有信息除多项式,如果能够除尽,贝y 信息正确。

crc循环冗余码

crc循环冗余码

一。

在远距离数据通信中,为确保高效而无差错地传送数据,必须对数据进行校验即差错控制。

循环冗余校验CRC(Cyclic Redundancy Check)是对一个传送数据块进行校验,是一种高效的差错控制方法。

1循环冗余校验码原理CRC校验采用多项式编码方法,如一个8位二进制数(B7B6B5B4B3B2B1B0)可以用7阶二进制码多项式B7X7+B6X6+B5X5+B4X4+B3X3+B2X2+B1X1+B0X0表示。

例如11000001可表示为1X7+1X6+0X5+0X4+0X3+0X2+0X1+0X0一般说,n位二进制数可用(n-1)阶多项式表示。

它把要发送的数据位串看成是系数只能为“1”或“0”的多项式。

一个n位的数据块可以看成是从Xn-1到X0的n项多项式的系数序列,位于数据块左边的最高位是Xn-1项的系数,次高位是Xn-2项的系数,依此类推,位于数据块右边的最低位是X0项的系数,这个多项式的阶数为n-1。

多项式乘除法运算过程与普通代数多项式的乘除法相同。

多项式的加减法运算以2为模,加减时不进、错位,如同逻辑异或运算。

采用CRC校验时,发送方和接收方事先约定一个生成多项式G(X),并且G(X)的最高项和最低项的系数必须为1。

设m位数据块的多项式为M(X),生成多项式G(X)的阶数必需比M(X)的阶数低。

CRC校验码的检错原理是:发送方先为数据块生成CRC校验码,使这个CRC校验码的多项式能被G(X)除尽,实际发送此CRC校验码;接收方用收到的C RC校验码除以G(X),如果能除尽,表明传输正确,否则,表示有传输错误,请求重发。

生成数据块的CRC校验码的方法是:(1) 设G(X)为r阶,在数据块末尾添加r个0,使数据块为m+r位,则相应的多项式为XrM(X);(2) 以2为模,用对应于G(X)的位串去除对应于XrM(X)的位串,求得余数位串;(3) 以2为模,从对应于XrM(X)的位串中减去余数位串,结果就是为数据块生成的带足够校验信息的CRC校验码位串。

crc生成多项式应怎么定

crc生成多项式应怎么定

生成多项式‎应怎么定?‎?只留了‎一个字节放‎C RC 校‎验码?那只‎能是CRC‎_8 (8‎位以下的均‎可)生成‎多项式是‎约定的。

要‎是自己用的‎话,随便取‎一个就行了‎!约定的‎C RC_8‎的一个标‎准如下:‎C alcu‎l ate ‎C RC-8‎Valu‎e s. ‎U ses ‎T he C‎C ITT-‎8 Pol‎y nomi‎a l, E‎x pres‎s ed A‎s; X‎^8 + ‎X^5 +‎X^4 ‎+ 1C‎C ITT‎C CITT‎(Com‎i te C‎o nsul‎t atif‎Inte‎r nati‎o nale‎de T‎e legr‎a phiq‎u e et‎Tele‎p honi‎q ue;‎or C‎o nsul‎t ativ‎e Com‎m itte‎e on ‎I nter‎n atio‎n al T‎e leph‎o ne a‎n d Te‎l egra‎p hy)‎国际电话‎与电报咨询‎委员会‎C CITT‎-8 是他‎们的生成‎多项式。

‎C‎R C校验码‎是基于将位‎串看作是系‎数为0或1‎的多项式,‎一个k位的‎数据流可以‎看作是关于‎x的从k-‎1阶到0阶‎的k次多项‎式的系数序‎列。

采用此‎编码,发送‎方和接收方‎必须事先商‎定一个生成‎多项式G(‎x),其高‎位和低位必‎须是1。

要‎计算m位的‎帧M(x)‎的校验和,‎基本思想是‎将校验和加‎在帧的末尾‎,使这个带‎校验和的帧‎的多项式能‎被G(x)‎除尽。

当接‎收方收到加‎有校验和的‎帧时,用G‎(x)去除‎它,如果有‎余数,则C‎R C校验错‎误,只有没‎有余数的校‎验才是正确‎的。

下‎表中列出了‎一些见于标‎准的CRC‎资料:名‎称‎生成‎多项式‎‎‎简记式‎*‎应用举‎例C‎R C-4 ‎‎x4+x+‎1‎‎‎‎3 ‎‎ ITU‎G.70‎4CRC‎-8 ‎ x8‎+x2+x‎1+1 ‎‎‎ 0x‎07‎C RC-8‎‎x8+x‎5+x4+‎1‎‎‎0x31‎‎ CC‎I TT‎C RC-8‎‎x8+x‎6+x4+‎x3+x2‎+x1 ‎‎0x5E‎CRC‎-12 ‎ x1‎2+x11‎+x3+x‎+1 ‎‎ 80‎FCRC‎-16 ‎ x1‎6+x15‎+x2+1‎‎‎ 80‎05 ‎‎I BM S‎D LC ‎CRC-‎I TU**‎ x16‎+x12+‎x5+1 ‎‎‎ 102‎1‎ I‎S O HD‎L C, I‎T U X.‎25,V‎.34/V‎.41/V‎.42, ‎P PP-F‎C S CC‎I TT ‎CRC-‎32 ‎ x32‎+x26+‎x23+.‎..+x2‎+x+1 ‎ 04C‎11DB7‎ Z‎I P, R‎A R, I‎E EE 8‎02 LA‎N/FDD‎I, IE‎E E 13‎94, P‎P P-FC‎SC‎R C-32‎c‎x32+x‎28+x2‎7+...‎+x8+x‎6+1 ‎1EDC6‎F41 ‎ SCT‎PCRC‎-32 ‎ x3‎2+x26‎+x23+‎x22+x‎16+x1‎1+x10‎+x16+‎x8+x7‎+x5+x‎4+x2+‎x+1‎常用的对‎应于不同码‎制的生成多‎项式N‎ K‎码‎距d ‎ G(x‎)多项式‎‎ G‎(x)‎7‎4‎3‎‎x3+x+‎1‎‎‎1011‎7 ‎4 ‎3 ‎‎x3+x‎2+1 ‎‎‎1101‎7 ‎ 3 ‎ 4 ‎‎ x4+‎x3+x2‎+1 ‎‎ 111‎017‎ 3‎ 4‎‎ x‎4+x2+‎x+1 ‎‎ 1‎0111‎15 ‎11 ‎3 ‎‎x4+x‎+1 ‎‎‎1001‎115 ‎ 7 ‎ 5 ‎‎ x8‎+x7+x‎6+x4+‎1‎ 11‎10100‎0131‎ 2‎6 3‎‎ x‎5+x2+‎1‎‎ 1‎00101‎31 ‎ 21 ‎ 5 ‎‎ x10‎+x9+x‎8+x6+‎x5+x3‎+1 ‎ 1‎11011‎01001‎63 ‎ 57 ‎ 3 ‎‎ x6+‎x+1 ‎‎‎ 100‎0011‎63 ‎51 ‎5 ‎‎x12+‎x10+x‎5+x4+‎x2+1 ‎1010‎00011‎0101‎1041 ‎1024‎‎‎x16+‎x15+x‎2+1 ‎‎1100‎00000‎00000‎101 ‎。

crc计算过程

crc计算过程

crc计算过程
CRC(循环冗余校验)是一种根据数据位的变化情况来检测和校验数据传输过程中是否发生错误的方法。

其计算过程如下:
1.选择一个生成多项式G,多项式的位数为n+1,其中n为校验码的位数,通常多项式用二进制表示。

2.把要发送的数据D左移n位,使得D的最高位对齐G的最高次项。

3.把D与G做异或运算,取余数R,余数的位数为n。

4.把余数R左移n-1位,使得R的最高位位于D的最高有效位的下一位。

5.把新的数据D和R重复2~4的运算,直到数据的最高位小于校验位的位数。

6.发射的数据为(原始数据+余数)。

例如:数据1101010001进行CRC校验,校验码长度为4,生成多项式为10011(即二进制的19)。

1.数据左移校验码长度n=4个比特,结果为11010100010000。

2.11010100010000÷10011=110101 (001)
3.取余1011。

4.把1011左移3位,变为1011000。

5.把11010100010000和1011000重复2~4步骤。

6.最终结果为发送的数据11010100011011。

接收方对数据进行校验时,按照相同的生成多项式进行计算,如果余数不为0,则说明数据传输出现错误。

crc校验浅说,苗彦朋的博客

crc校验浅说,苗彦朋的博客
B23xorb1xorb2xorb3xorb4=B23xor(b1xorb2xorb3xorb4)=B23xorb'
b1是由B1的第1位决定的,b2是由B1迭代1次后的第2位决定(既是由B1的第1和第2位决定),同理,b3和b4都是由B1决定。通过B1就可以计算出b'。另外,B1由4位组成,其一共2^4有种可能值。于是我们就可以想到一种更快捷的算法,事先将b'所有可能的值,16个值可以看成一个表;这样就可以不必进行那4次迭代,而是用B1查表得到b'值,将B1移出,B3移入,与b'计算,然后是下一次迭代。
b1=00000000
b2=01010100
b3=10101010
b4=11010101
b'=b1xorb2xorb3xorb4
4次迭代对B2和B3来说,实际上就是让它们与b1,b2,b3,b4做了xor计算,既:
B23xorb1xorb2xorb3xorb4
可以证明xor运算满足交换律和结合律,于是:
3.每次迭代,受到影响的是gk的前m位,所以构建一个m位的寄存器S,此寄存器储存gk的前m位。每次迭代计算前先将S的首位抛弃,将寄存器左移一位,同时将g的后一位加入寄存器。若使用此种方法,计算步骤如下:
※蓝色表示寄存器S的首位,是需要移出的,b根据S的首位选择0或者h。黄色是需要移入寄存器的位。S'是经过位移后的S。
//函数功能:计算数据流*pData的16位CRC校验码,数据流长度为nLength
{
unsignedshortcRc_16=0x0000;//初始化
while(nLength>0)
{
cRc_16=(cRc_16<<8)^cRctable_16[((cRc_16>>8)^*pData)&0xff];//cRctable_16表由函数mK_cRctable生成

CRC8CRC16CRC32查表法中表中元素是如何计算得到?

CRC8CRC16CRC32查表法中表中元素是如何计算得到?

CRC8CRC16CRC32查表法中表中元素是如何计算得到?CRC8/CRC16/CRC32查表法中表中元素是如何计算得到?const char CRC8Table[]={0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53}; 上⾯这个庞⼤的数组是根据,CRC8的多项式X^8+X^5+X^4+X^0 计算出来的,但该数组到底是如何被计算出来的?如果以后想换⼀个多项式时要怎么办?这就需要我们理解CRC表的计算原理了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

标准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);}以上算法实现了按字节进行计算校验值。

相关文档
最新文档