诛仙3 data4.pckdata5.pck CRC,谁发我...

生成方法/CRC校验
CRC校验借助于模2除法则,其馀数为校验字段。例如:信息字段代码为:1011001;对应m(x)=x6+x4+x3+1假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为:11001x4m(x)=x10+x8+x7+x4对应的代码记为:;采用模2除法则:得馀数为:1010(即校验字段为:1010)发送方:发出的传输字段为:信息字段校验字段接收方:使用相同的生成码进行校验:接收到的字段/生成码(二进制除法)如果能够除尽,则正确,给出馀数(1010)的计算步骤:除法没有数学上的含义,而是采用计算机的模二除法,即除数和被除数做异或运算。进行异或运算时除数和被除数最高位对齐,按位异或。^11001--------------------------^11001-------------------------^11001--------------------------111000^11001-------------------001010则四位CRC校验码就为:1010。利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为“生成多项式”。
算法/CRC校验
在代数编码理论中,将一个码组表示为一个多项式,码组中各码元当作多项式的系数。例如 1100101 表示为1?x+1?x+0?x+0?x+1?x+0?x+1,即 x+x+x+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 G(x)= x3+x+1 即 R(x)=x。注意到G(x)最高幂次r=3,得出CRC为010。如果用竖式除法(计算机的模二,计算过程为1110 ------- 0 (1100左移3位) 1011 ----
---- 010 因此,T(x)=(x6+x5)+(x)=x6+x5+x, 即 =1100010如果传输无误,CRC校验T(x)= (x6+x5+x)/G(x) = , G(x)= 无馀式。回头看一下上面的竖式除法,如果被除数是1100010,显然在商第三个1时,就能除尽。上述推算过程,有助于我们理解CRC的概念。但直接编程来实现上面的算法,不仅繁琐,效率也不高。实际上在工程中不会直接这样去计算和验证CRC。下表中列出了一些见于标准的CRC资料:
生成多项式
x8+x5+x4+1
x12+x11+x3+x+1
x16+x15+x2+1
x16+x12+x5+1
ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS,ZigBee
x32+x26+x23+...+x2+x+1
ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
x32+x28+x27+...+x8+x6+1
* 生成多项式的最高幂次项系数是固定的1,故在简记式中,将最高的1统一去掉了,如04C11DB7实际上是104C11DB7。 ** 前称CRC-CCITT。ITU的前身是CCITT。备注:(1)生成多项式是标准规定的(2)CRC校验码是基于将位串看作是系数为0或1的多项式,一个k位的数据流可以看作是关于x的从k-1阶到0阶的k-1次多项式的系数序列。采用此编码,发送方和接收方必须事先商定一个生成多项式G(x),其高位和低位必须是1。要计算m位的帧M(x)的校验和,基本思想是将校验和加在帧的末尾,使这个带校验和的帧的多项式能被G(x)除尽。当接收方收到加有校验和的帧时,用G(x)去除它,如果有馀数,则CRC校验错误,只有没有馀数的校验才是正确的。(3) 名称 生成多项式 简记式* 标准引用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。
校验电路实现/CRC校验
以下以CRC8x8+x5+x4+1为例说明,其它可以以此类推生成算法一个简单的RTL解释,是上文“生成方法”的Verilog描述module CRC8(EN,data,crc);parameter WIDTH=12;input EN;output[7:0]input[WIDTH-1:0]reg[7:0]wire[7:0]poly=8'h31;//x8+x5+x4+1-->0x131,ignore MSBreg[WIDTH-1+8:0]crc_always@(EN)beginif(!EN)begincrc=8'h00;crc_reg={data,8'h00};endelsebeginfor(len=WIDTH;len>0;len=len-1'b1)beginif(crc_reg[WIDTH-1+8])begincrc_reg=crc_reg<<1'b1;crc_reg[WIDTH-1+8:WIDTH]=crc_reg[WIDTH-1+8:WIDTH]^endelsecrc_reg=crc_reg<<1'b1;endcrc=crc_reg[WIDTH-1+8:WIDTH];$display("Convertion done! CRC is: 0x%2x",crc);endendendmodule检测电路CRC-8的电路框图module crc(dataout,datain,clk,rst);input clk,rst,DFF a1(clk,dataout,Q7,rst),a2(clk,Q7,Q6,rst),a3(clk,Q6,Q5,rst),a4(clk,Q5,Q4,rst);xor a5(temp5,Q4,dataout);DFF a6(clk,temp5,Q3,rst);xor a7(temp4,Q3,dataout);DFF a8(clk,temp4,Q2,rst),a9(clk,Q2,Q1,rst),a10(clk,Q1,Q0,rst);xor a11(dataout,Q0,datain);endmodule////////////////////////////////////////module DFF(clk,D,Q,rst);input clk,D,output Q;Verilog简单测试reg Q;always@(posedge clk or posedge rst)beginif(rst)Q<=0;elseQ<=D;endendmodule
&|&相关影像
互动百科的词条(含所附图片)系由网友上传,如果涉嫌侵权,请与***联系,我们将按照法律之相关规定及时进行处理。未经许可,禁止商业网站等复制、抓取本站内容;合理使用者,请注明来源于。
登录后使用互动百科的服务,将会得到个性化的提示和帮助,还有机会和专业认证智愿者沟通。
此词条还可添加&
编辑次数:10次
参与编辑人数:5位
最近更新时间: 05:44:24
申请可获得以下专属权利:
贡献光荣榜CRC校验原理与程序设计----(RS485总线系统应用之1)
《CRC校验原理与程序设计》
东风汽车有限公司计量测试中心王德宪
内容摘要:
本文介绍了CRC校验的基本概念和计算原理,分别用VC、VB两种编程语言和计算、查表两种方法,给出了求解CRC函数的程序清单,可供有关技术人员学习借用。
CRC校验、循环冗余校验、校验原理、程序设计
1.CRC校验原理
1.1 CRC的基本概念:
CRC是英文Cyclical Redundancy
Check的缩写,翻译成中文通常称作循环冗余校验或简称为CRC校验。它是数据传输领域中最常用的一种差错校验方法,其特点是传输数据和CRC校验值的长度可以任意选定。在当今手机、计算机和数码产品普及的信息数字化时代,CRC校验无处不在。CRC分为多种标准,例如:CRC -12码通常用来传送6-bit字符串。CRC-16及CRC-CCITT码则用是来传送8-bit字符,其中CRC-16多为美国采用,而CRC-CCITT多为欧洲国家所采用。而CRC-32码大都被应用在Point-to-Point的同步传输中。更多的CRC校验标准类型参见附表:CRC校验标准类型。
1.2 CRC校验的基本原理:
在代数编码理论中,一个数值可以表示为一个多项式。例如:一个十进制数值2892,可以用多项式表示为2x3 + 8x2 + 9x +
2(x=10)。同理,一个二进制数值1010101对应的多项式为x6 + x4 + x2 +
生成CRC码的基本原理是:设被校验的数据为K位,校验码为R位,码字长度为N(=K+R),则对于CRC码集中的任一码字,存在且仅存在一个R次多项式g(x),使得
  V(x)=A(x)g(x)=xRm(x) +
  其中: m(x)为被校验数据的K-1次多项式
&&&&&&r(x)为校验码的R-1次多项式
g(x)称为生成多项式:g(x)=g0 + g1x1 + g2x2 +
... + g(R-1)x(R-1) + gRxR
发送方通过指定的g(x)计算出CRC校验码,接收方则通过该g(x)来验证收到的CRC校验码。综上所述,一个完整的CRC校验过程是:
发送方:根据要传送的K位原始数据(二进制码序列),以标准指定的多项式计算出一个R位校验码(CRC码),附在原始数据后边,构成一个新的二进制码序列共K + R位,然后发送出去。
接收方:将接收到的数据除以与发送方相同的多项式值,如果能够除尽,则正确,否则证明出错。还有另外一种处理,就是接收方用发送方相同的方法计算出接收到数据的CRC校验值,再与发送方发来的校验值比较,相同则正确,否则证明出错。
CRC校验码的计算步骤:
例如:有一个要发送的7位二进制数1011001;对应的m(x)=x6 + x4 + x3 +
1。设CRC校验码取4位并设g(x)=x4 + x + 1,则该多项式对应的值是10011。根据CRC规则,为保证被除数够除,首先需将要发送的数扩大2R 即24倍(左移4位),得到,对应的xRm(x)=x10 + x8 +
x7 + x4 。
CRC校验码的生成本质其实就是采用模2除法取余数,该除法的简捷计算就是将除数和被除数按位做异或(相同为0,不同为1。0^0=0; 0^1=1;
1^1=0)运算。需要注意的是,进行异或运算时除数必须和被除数最高有效位对齐。下面是将除以11001手工计算的演示,得到余数为1010,该值即是数据1011001的CRC校验值。
&&&&&&&&将1011001左移4位
   10011&&&&&&&&&&&&&&&&&
多项式值与被除数最高有效位对齐
  =&&&&&&&&&&&
第1次异或结果
   &&10011&&&&&&&&&&&&&&&
多项式值与被除数最高有效位对齐
  =&&&&&&&&&&&
第2次异或结果
   &&&&10011&&&&&&&&&&&&&
多项式值与被除数最高有效位对齐
  =&&&&&&&&&&&
第3次异或结果
   &&&&&10011&&&&&&&&&&&&
多项式值与被除数最高有效位对齐
  =&&&&&&&&&&&
第4次异或结果
为了简便计算机程序求解CRC,在实际应用中通常把多项式值的最高位舍掉,并且将参加计算的数据高低位颠倒后再计算。前面的演算数据颠倒后的运算情况如下:
提请注意:只有真正读懂以上手工演算的步骤和规律,才能理解下节内容。
CRC校验的程序设计
下面以最常用的CRC-16-IBM校验标准为例来说明CRC校验码的生成过程。 因为CRC-16码由两个字节构成,所以首先要准备一个16位的CRC寄存器,并将每一位都置1。具体的计算步骤为:
① 设置CRC寄存器,并给其赋值FFFFH。
将被校验数据的第一个字节(8Bit)与CRC寄存器的低8位进行异或,结果存CRC寄存器。
③ CRC寄存器的值向右移一位,最高位(MSB)补零,检查移出的最低位(LSB)是否为1。
④ 如果LSB为0,重复第三步;若LSB为1,CRC寄存器与CRC16多项式值A001H相异或。
重复第③与第④步,直到该字节的8次移位全部完成。
如果被校验数据有多个字节,则重复第②至第⑤步直到所有数据全部处理完。
⑦ 最终CRC寄存器的内容即为CRC值。
3.1 用查表法求CRC函数的程序
& &&查表法省去了将被校验数据移位并与多项式异或计算的步骤,因此比计算法更快捷,但程序编码量偏大。
3.1.1 用VC编写的程序
unsigned short CRC16(puchMsg,
usDataLen)
unsigned char * puchM &&&&&&&&&&&&&&&&&&&
unsigned short usDataL &&&&&&&&&&&&&&&&&&
&unsigned char uchCRCHi
= 0xFF ; &&&&&&&&&&&
&unsigned char uchCRCLo
= 0xFF ; &&&&&&&&&&&
&unsigned uI
&&&&&&&&&&&&&&&&&&&&&&&&&
&while (usDataLen--)
&&&&&&&&&&&&&&&&&&&&&&&
uIndex = uchCRCLo ^ * puchMsg++ ;&&&&&&
uchCRCLo = uchCRCHi ^ auchCRCLo [uIndex] ;
uchCRCHi = auchCRCHi [uIndex] ;
& return (uchCRCLo
&& 8 | uchCRCHi) ;
static char auchCRCHi[] = {
& 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, 0x2D, 0xED,
& 0xEC, 0x2C, 0xE4,
0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
& 0x22, 0xE2, 0xE3,
0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
& 0x61, 0xA1, 0x63,
0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
& 0xA5, 0x65, 0x64,
0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
& 0x6E, 0xAE, 0xAA,
0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
& 0x78, 0xB8, 0xB9,
0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
& 0x7F, 0xBF, 0x7D,
0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
& 0x77, 0xB7, 0xB6,
0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
& 0x70, 0xB0, 0x50,
0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
& 0x96, 0x56, 0x57,
0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
& 0x5D, 0x9D, 0x5F,
0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
& 0x99, 0x59, 0x58,
0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
& 0x8A, 0x4A, 0x4E,
0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
& 0x44, 0x84, 0x85,
0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
& 0x43, 0x83, 0x41,
0x81, 0x80, 0x40 } ;
static unsigned char auchCRCLo[] = {
& 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 } ;
3.1.2 用VB编写的程序
Private Function CRC16(data() As Byte) As
 Dim CRC16Hi As Byte
 Dim CRC16Lo As Byte
 CRC16Hi = &HFF
 CRC16Lo = &HFF
 Dim i As Integer
 Dim iIndex As Long
 For i = 0 To UBound(data)
  iIndex = CRC16Lo Xor data(i)
  CRC16Lo = CRC16Hi Xor GetCRCLo(iIndex)&&&
’低位处理
CRC16Hi = GetCRCHi(iIndex)&&&&&&&&&&&&&&&
’高位处理
 Dim ReturnData(1) As Byte
 ReturnData(0) = CRC16Hi&&&&&&&&&&&&&&&&&&&&
 ReturnData(1) = CRC16Lo&&&&&&&&&&&&&&&&&&&&
 CRC16 = ReturnData
End Function
Function GetCRCHi(Ind As Long) As Byte&&&&
’CRC高位字节值表
GetCRCHi = Choose(Ind + 1,_
&HC0, &HC1, &H01,
&HC3, &H03, &H02,
&HC2, &HC6,
&HC7, &H05, &HC5,
&HC4, &H04, &HCC,
&H0C, &H0D,
&HCF, &HCE, &H0E,
&H0A, &HCA, &HCB,
&H0B, &HC9,
&HC8, &HD8, &H18,
&H19, &HD9, &H1B,
&HDB, &HDA,
&HDE, &HDF, &H1F,
&HDD, &H1D, &H1C,
&HDC, &H14,
&H15, &HD7, &H17,
&H16, &HD6, &HD2,
&H12, &H13,
&HD1, &HD0, &H10,
&HF0, &H30, &H31,
&HF1, &H33,
&H32, &H36, &HF6,
&HF7, &H37, &HF5,
&H35, &H34,
&HFC, &HFD, &H3D,
&HFF, &H3F, &H3E,
&HFE, &HFA,
&HFB, &H39, &HF9,
&HF8, &H38, &H28,
&HE8, &HE9,
&H2B, &H2A, &HEA,
&HEE, &H2E, &H2F,
&HEF, &H2D,
&H2C, &HE4, &H24,
&H25, &HE5, &H27,
&HE7, &HE6,
&HE2, &HE3, &H23,
&HE1, &H21, &H20,
&HE0, &HA0,
&HA1, &H63, &HA3,
&HA2, &H62, &H66,
&HA6, &HA7,
&H65, &H64, &HA4,
&H6C, &HAC, &HAD,
&H6D, &HAF,
&HAE, &HAA, &H6A,
&H6B, &HAB, &H69,
&HA9, &HA8,
&HB8, &HB9, &H79,
&HBB, &H7B, &H7A,
&HBA, &HBE,
&HBF, &H7D, &HBD,
&HBC, &H7C, &HB4,
&H74, &H75,
&HB7, &HB6, &H76,
&H72, &HB2, &HB3,
&H73, &HB1,
&HB0, &H50, &H90,
&H91, &H51, &H93,
&H53, &H52,
&H56, &H57, &H97,
&H55, &H95, &H94,
&H54, &H9C,
&H9D, &H5F, &H9F,
&H9E, &H5E, &H5A,
&H9A, &H9B,
&H59, &H58, &H98,
&H88, &H48, &H49,
&H89, &H4B,
&H4A, &H4E, &H8E,
&H8F, &H4F, &H8D,
&H4D, &H4C,
&H84, &H85, &H45,
&H87, &H47, &H46,
&H86, &H82,
&H83, &H41, &H81,
&H80, &H40)
End Function
Function GetCRCLo(Ind As Long) As Byte&&&
&’CRC低位字节值表
GetCRCLo = Choose(Ind + 1,_
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H01,
&H41, &H00, &HC1,
&H81, &H40, &H01,
&HC0, &H80,
&HC1, &H81, &H40,
&H00, &HC1, &H81,
&H40, &H01,
&H41, &H01, &HC0,
&H80, &H41, &H00,
&HC1, &H81,
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H00,
&H40, &H01, &HC0,
&H80, &H41, &H01,
&HC0, &H80,
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H00,
&H40, &H00, &HC1,
&H81, &H40, &H01,
&HC0, &H80,
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H01,
&H41, &H00, &HC1,
&H81, &H40, &H00,
&HC1, &H81,
&HC0, &H80, &H41,
&H01, &HC0, &H80,
&H41, &H00,
&H40, &H01, &HC0,
&H80, &H41, &H00,
&HC1, &H81,
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H01,
&H41, &H00, &HC1,
&H81, &H40, &H00,
&HC1, &H81,
&HC0, &H80, &H41,
&H00, &HC1, &H81,
&H40, &H01,
&H41, &H01, &HC0,
&H80, &H41, &H00,
&HC1, &H81,
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H01,
&H41, &H00, &HC1,
&H81, &H40, &H01,
&HC0, &H80,
&HC1, &H81, &H40,
&H00, &HC1, &H81,
&H40, &H01,
&H41, &H00, &HC1,
&H81, &H40, &H01,
&HC0, &H80,
&HC0, &H80, &H41,
&H00, &HC1, &H81,
&H40, &H01,
&H41, &H00, &HC1,
&H81, &H40, &H00,
&HC1, &H81,
&HC0, &H80, &H41,
&H01, &HC0, &H80,
&H41, &H00,
&H40, &H00, &HC1,
&H81, &H40, &H01,
&HC0, &H80,
&HC1, &H81, &H40,
&H01, &HC0, &H80,
&H41, &H01,
&H41, &H00, &HC1,
&H81, &H40)
End Function
3.2 用计算法求CRC函数的程序
计算法的优点是程序编码量小,虽然比查表法速度偏慢,但当被校验的数据量不大时并不明显。
3.2.1 用VC编写的程序
unsigned short CRC16(unsigned char buf[], int
unsigned short crc = 0
for(i = 0; i & i++)
crc ^ = buf[i] ;
for(b = 0; b & 8; b++)
f = crc & 1 ;
crc && = 1 ;
crc ^ = 0xa001 ;
return(crc) ;
3.2.2 用VB编写的程序
Function CRC16(Data() As Byte, No As Integer,
CRC16Lo As Byte, CRC16Hi As Byte) As String
CL As Byte, CH As Byte, SaveLo As Byte, SaveHi As Byte
CRC16Hi = &HFF&&&&&&&&&&&&&&&&&&&&&&&&&&&
'为16位CRC校验寄存器赋初始值 FFFF
CRC16Lo = &HFF
= &HA0&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
'为16位CRC校验多项式赋初始值 A001
i = 1 To No
CRC16Lo = CRC16Lo Xor Data(i - 1)&&&&&
'每一个数据与CRC寄存器进行异或
For j = 1 To 8
SaveHi = CRC16Hi
SaveLo = CRC16Lo
CRC16Hi = CRC16Hi \ 2&&&&&&&&&&&&&&
'高位右移一位
CRC16Lo = CRC16Lo \ 2&&&&&&&&&&&&&&
'低位右移一位
If ((SaveHi And &H1) = &H1)
'如果高位字节最右一位为1
&&&&&&&&&&&
CRC16Lo = CRC16Lo Or &H80&&&&&&&
'则低位字节最左一位补1,否则自动补0
If ((SaveLo And &H1) = &H1)
'如低位字节最右一位为1,则与多项式值异或
&&&&&&&&&&&
CRC16Hi = CRC16Hi Xor CH
&&&&&&&&&&&
CRC16Lo = CRC16Lo Xor CL
End Function
参考文献:
① GB/T 8《基于Modbus协议的工业自动化网络规范》
②《Modbus协议中文版》&
可在互联网上下载
CRC校验标准类型
(标准引用名)
对应的16进制值或反值注:已去掉最高位的1
x + 1 ( also known as
parity bit)
或 01 (01)
x4 + x + 1 (ITU
G.704, p. 12)
或 0C (09)
+ x2 + 1 (ITU G.704, p. 9)
或 15 (1A)
+ 1 (USB token packets)
或 14 (12)
x6 + x + 1 (ITU
G.704, p. 3)
或 30 (21)
+ 1 (telecom systems, MMC,SD)
或 48 (44)
+ x + 1 (ATM HEC)
或 E0 (83)
CRC-8-CCITT
+ x3 + x2 + 1 (1-Wire
或 B1 (C6)
CRC-8-Dallas/Maxim
+ x4 + 1 (1-Wire bus)
或 8C (98)
+ x6 + x4 +
或 AB (EA)
CRC-8-SAE J1850
+ x3 + x2 + 1
或 B8 (8E)
+ x5 + x4 + x +
或 331 (319)
+ x8 + x7 + x + 1
或 50E (5C2)
x11 + x3 + x2
+ x + 1 (telecom systems )
或 F01 (C07)
CRC-15-CAN
x14 + x10 +
x8 + x7 + x4
或 4CD1 (62CC)
CRC-16-Fletcher
Not a CRC; see Fletcher's
Used in Adler-32 A &
CRC-16-CCITT
x12 + x5 + 1 (CRC-CCITT, G.hn
PHY headers, 802.15.4, X.25, V.41, CDMA, Bluetooth, XMODEM,
HDLC,PPP, IrDA, BACnet, MMC,SD)
CRC-16-DNP
x13 + x12 +
x11 + x10 +
x8 + x6 + x5
+ x2 + 1 (DNP, IEC 870, M-Bus)
或 A6BC (9EB2)
CRC-16-IBM
x15 + x2 + 1 (CRC-16, SDLC,
USB, many others)
或 A001 (C002)
CRC-24-Radix-64
x23 + x18 +
x17 + x14 +
x11 + x10 +
x7 + x6 + x5
+ x4 + x3 + x + 1
x29 + x21 +
x20 + x15 +
x13 + x12 +
x11 + x8 + x7
+ x6 + x2 + x + 1
或 38E74301
(30185CE3)
CRC-32-Adler
Not a CRC; see Adler-32
See Adler-32
CRC-32-IEEE 802.3
x26 + x23 +
x22 + x16 +
x12 + x11 +
x10 + x8 + x7
+ x5 + x4 +
x2 + x + 1 (V.42, MPEG-2, PNG [10], POSIX
或 EDB88320
(82608EDB)
CRC-32C (Castagnoli)
x32 + x28 +
x27 + x26 + x25 + x23 +
x22 + x20 + x19 + x18 +
x14 + x13 + x11 + x10 +
x9 + x8 + x6 + 1 (G.hn
或 82F63B78
(8F6E37A0)
CRC-32K (Koopman)
x30 + x29 +
x28 + x26 +
x20 + x19 +
x17 + x16 +
x15 + x11 +
x10 + x7 + x6
+ x4 + x2 + x +
或 EB31D82E
(BA0DC66B)
CRC-64-ISO
+ x3 + x + 1 (HDLC-ISO 3309)
CRC-64-ECMA-182
x64 + x62 +
x57 + x55 + x54 + x53 +
x52 + x47 + x46 + x45 +
x40 + x39 + x38 + x37 +
x35 + x33 + x32 + x31 +
x29 + x27 + x24 + x23 +
x22 + x21 + x19 + x17 +
x13 + x12 + x10 + x9 +
x7 + x4 + x + 1 (As described in ECMA-182
42F0E1EBA9EA3693
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

参考资料

 

随机推荐