紫外工控论坛

 找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 4027|回复: 0

[VB/VB.NET] CRC校验原理及其C语言实现

[复制链接]
冰糖 发表于 2010-6-27 21:12:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
  1. CRC校验码的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码)r位,并附在信息后边,构成一个新的二进制码序列数共(k+ r)位,最后发送出去。在接收端,则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。
  2.       在数据存储和数据通讯领域,CRC无处不在:著名的通讯协议X.25的FCS(帧检错序列)采用的是CRC. CCITT,ARJ、LHA等压缩工具软件采用的是CRC32,磁盘驱动器的读写采用了CRC16,通用的图像存储格式GIF、TIFF等也都用CRC作为检错手段。
  3.       CRC的本质是模-2除法的余数,采用的除数不同,CRC的类型也就不一样。通常,CRC的除数用生成多项式来表示。最常用的CRC码的生成多项式有CRC16,CRC32.
  4.       以CRC16为例,16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(既乘以2^16)后,再除以一个多项式,最后所得到的余数既是 CRC码,如下式所示,其中K(X)表示n位的二进制序列数,G(X)为多项式,Q(X)为整数,R(X)是余数(既CRC码)。
  5. K(X)>>16=G(x)Q(x)+R(x)
  6.       求CRC码所采用模2加减运算法则,既是不带进位和借位的按位加减,这种加减运算实际上就是逻辑上的异或运算,加法和减法等价,乘法和除法运算与普通代数式的乘除法运算是一样,符合同样的规律。生成CRC码的多项式如下,其中CRC-16和CRC-CCITT产生16位的CRC码,而CRC-32则产生的是32位的CRC码
  7. PLC资料网

  8.       接收方将接收到的二进制序列数(包括信息码和CRC码)除以多项式,如果余数为0,则说明传输中无错误发生,否则说明传输有误,关于其原理这里不再多述。用软件计算CRC码时,接收方可以将接收到的信息码求CRC码,比较结果和接收到的CRC码是否相同。
  9.       CCITT推荐的高级数据链路控制规程HDLC的帧校验序列FCS中,使用CCITT-16即CRC16,其生成多项式为G(x)=x16+x12+x5 +1, CRC-32的生成多项式为G(x)=x32+x26+x23+x22+x16+x11+x10+x16+x8+x7+x5+x4+x2+x+1

  10.       以上是摘录的一段介绍,是不是觉得很玄?我第一次看也是觉得很晕,后来查询了一些规约和协议的实现资料以后,才恍然大悟。以下是我实现的一段C++代码,只实现了CRC16,CRC32的实现基本类似,网上有很多资源。其实实现起来非常简单,就是查表、异或运算而已!查表法实现起来比较简单,耗资源也比较少,速度较快。只要通信双方采用的同样的余数表,就可以正确进行CRC校验。余数表并没有硬性规定。许多程序还把余数表做成自动生成,那样适用性就更好了。

  11. //CRC计算主函数:
  12. //内容:
  13. #include "CrcCode.h"
  14. PLC
  15. using namespace std;

  16. unsigned short int CrcCode::CrcCode16(const char *CrcSrcCode,const size_t CodeLength)
  17. {
  18.       unsigned short CRC_Code[]={
  19.               0x0673,0x1652,0x2631,0x3610,0x46F7,0x56D6,0x66B5,0x7694,0x877B,0x975A,//10
  20.               0xA739,0xB718,0xC7FF,0xD7DE,0xE7BD,0xF79C,0x1442,0x0463,0x3400,0x2421,//20
  21.               0x54C6,0x44E7,0x7484,0x64A5,0x954A,0x856B,0xB508,0xA529,0xD5CE,0xC5EF,//30
  22.               0xF58C,0xE5AD,0x2211,0x3230,0x0253,0x1272,0x6295,0x72B4,0x42D7,0x52F6,//40
  23.               0xA319,0xB338,0x835B,0x937A,0xE39D,0xF3BC,0xC3DF,0xD3FE,0x3020,0x2001,//50
  24.               0x1062,0x0043,0x70A4,0x6085,0x50E6,0x40C7,0xB128,0xA109,0x916A,0x814B,//60
  25. PLC资料网

  26.               0xF1AC,0xE18D,0xD1EE,0xC1CF,0x4EB7,0x5E96,0x6EF5,0x7ED4,0x0E33,0x1E12,//70
  27.               0x2E71,0x3E50,0xCFBF,0xDF9E,0xEFFD,0xFFDC,0x8F3B,0x9F1A,0xAF79,0xBF58,//80
  28.               0x5C86,0x4CA7,0x7CC4,0x6CE5,0x1C02,0x0C23,0x3C40,0x2C61,0xDD8E,0xCDAF,//90
  29.               0xFDCC,0xEDED,0x9D0A,0x8D2B,0xBD48,0xAD69,0x6AD5,0x7AF4,0x4A97,0x5AB6,//100
  30.               0x2A51,0x3A70,0x0A13,0x1A32,0xEBDD,0xFBFC,0xCB9F,0xDBBE,0xAB59,0xBB78,//110
  31.               0x8B1B,0x9B3A,0x78E4,0x68C5,0x58A6,0x4887,0x3860,0x2841,0x1822,0x0803,//120
  32.               0xF9EC,0xE9CD,0xD9AE,0xC98F,0xB968,0xA949,0x992A,0x890B,0x97FB,0x87DA,//130
  33. PLC

  34.               0xB7B9,0xA798,0xD77F,0xC75E,0xF73D,0xE71C,0x16F3,0x06D2,0x36B1,0x2690,//140
  35.               0x5677,0x4656,0x7635,0x6614,0x85CA,0x95EB,0xA588,0xB5A9,0xC54E,0xD56F,//150
  36.               0xE50C,0xF52D,0x04C2,0x14E3,0x2480,0x34A1,0x4446,0x5467,0x6404,0x7425,//160
  37.               0xB399,0xA3B8,0x93DB,0x83FA,0xF31D,0xE33C,0xD35F,0xC37E,0x3291,0x22B0,//170
  38.               0x12D3,0x02F2,0x7215,0x6234,0x5257,0x4276,0xA1A8,0xB189,0x81EA,0x91CB,//180
  39.               0xE12C,0xF10D,0xC16E,0xD14F,0x20A0,0x3081,0x00E2,0x10C3,0x6024,0x7005,//190
  40.               0x4066,0x5047,0xDF3F,0xCF1E,0xFF7D,0xEF5C,0x9FBB,0x8F9A,0xBFF9,0xAFD8,//200 PLC资料网
  41.               0x5E37,0x4E16,0x7E75,0x6E54,0x1EB3,0x0E92,0x3EF1,0x2ED0,0xCD0E,0xDD2F,//210
  42.               0xED4C,0xFD6D,0x8D8A,0x9DAB,0xADC8,0xBDE9,0x4C06,0x5C27,0x6C44,0x7C65,//220
  43.               0x0C82,0x1CA3,0x2CC0,0x3CE1,0xFB5D,0xEB7C,0xDB1F,0xCB3E,0xBBD9,0xABF8,//230
  44.               0x9B9B,0x8BBA,0x7A55,0x6A74,0x5A17,0x4A36,0x3AD1,0x2AF0,0x1A93,0x0AB2,//240
  45.               0xE96C,0xF94D,0xC92E,0xD90F,0xA9E8,0xB9C9,0x89AA,0x998B,0x6864,0x7845,//250
  46.               0x4826,0x5807,0x28E0,0x38C1,0x08A2,0x1883                               //256
  47. PLC

  48.       };                                                     //CRC_Code[]数组就是一个余数表
  49.           unsigned short int n_CrcCode16=0;
  50.           unsigned short int location=0;
  51.           for(size_t i=0;i!=CodeLength;i++)
  52.           {
  53.               location=(n_CrcCode16 & 0xff)^(CrcSrcCode[i] & 0xff);             //查表,事实上就是获取该余数在CRC_Code[]数组的中的位置
  54.               n_CrcCode16=((n_CrcCode16>>8) & 0xff) ^ CRC_Code[location];       //从表中取值计算
  55. PLC资料网

  56.           }
  57.           std::cout<<"The CrcCode you need is:"<<n_CrcCode16<<endl;
  58.           return n_CrcCode16;
  59. }

  60.       当然了,你要做的就是给它传递参数,也就是你要计算的数据,char类型。一般的串口通信、网络通信都是字符型通信,更适用于LINUX里面的字符型设备。这个类是在Suse10.1下面用Kdevelop写的,全部使用ANSI C/C++编写,在Linux和Windows均可以编译通过并且正确运行。
  61. /************************************************************
  62. crc16校验程序
  63. uint crc16(uint crcdata,uchar bufdata)
  64. 形参:bufdata     需要校验数据
  65.        crcdata     校验后的数据
  66. 功能:接收字节crc校验,返回校验值
  67. *************************************************************/
  68. uint crc16(uint crcdata,uchar bufdata)
  69. {
  70. uchar i;
  71. PLC资料网

  72.    
  73. crcdata^=bufdata;
  74. for(i=8;i>0;i--)
  75. {
  76.       crcdata>>=1;
  77.       if(crcdata&0x01)
  78.       crcdata^=0xa001;
  79.      }
  80. return crcdata;
  81. }
  82. VBvbvbvbvbvbvbvvvvvvvvvvvvvvvvvvbbbbbbbbbbbbbbbbbb
  83. Private Sub Command1_Click()
  84.           Dim CRC()       As Byte
  85.           Dim d()       As Byte       '待传输数据
  86.           ReDim d(5) As Byte
  87.           d(0) = 2 '02 03 00 00 00 04    lo44 hi3A
  88.           d(1) = 3
  89.           d(2) = 0
  90. PLC

  91.           d(3) = 0
  92.           d(4) = 0
  93.           d(5) = 4 '02 03 20 40 00 04    hi2E Lo4E
  94.       
  95.           CRC = CRC16(d)         '调用CRC16计算函数
  96.           'CRC(0)为高位
  97.           'CRC(1)为低位
  98.         End Sub
  99.         '注意:在数据传输时CRC的低位可能在前,而高位在后。
  100.    
  101.         Function CRC16(data() As Byte) As String
  102.           Dim CRC16Lo       As Byte, CRC16Hi         As Byte          'CRC寄存器 PLC
  103.           Dim CL       As Byte, CH         As Byte                    '多项式码&HA001
  104.           Dim SaveHi       As Byte, SaveLo         As Byte
  105.           Dim i       As Integer
  106.           Dim Flag       As Integer
  107.           CRC16Lo = &HFF
  108.           CRC16Hi = &HFF
  109.           CL = &H1
  110.           CH = &HA0
  111.           For i = 0 To UBound(data) PLC
  112.             CRC16Lo = CRC16Lo Xor data(i)             '每一个数据与CRC寄存器进行异或
  113.             For Flag = 0 To 7
  114.               SaveHi = CRC16Hi
  115.               SaveLo = CRC16Lo
  116.               CRC16Hi = CRC16Hi \ 2                      '高位右移一位
  117.               CRC16Lo = CRC16Lo \ 2                      '低位右移一位
  118.               If ((SaveHi And &H1) = &H1) Then                 '如果高位字节最后一位为1 PLC资料网
  119.                 CRC16Lo = CRC16Lo Or &H80                '则低位字节右移后前面补1
  120.               End If                                 '否则自动补0
  121.               If ((SaveLo And &H1) = &H1) Then                 '如果LSB为1,则与多项式码进行异或
  122.                 CRC16Hi = CRC16Hi Xor CH
  123.                 CRC16Lo = CRC16Lo Xor CL
  124. PLC资料网


  125.               End If
  126.             Next Flag
  127.           Next i
  128.           Dim ReturnData(1)       As Byte
  129.           ReturnData(0) = CRC16Hi                    'CRC高位
  130.           ReturnData(1) = CRC16Lo                    'CRC低位
  131.           CRC16 = ReturnData
  132.         End Function
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


--------------------------------------------------------------------------------------------------------------------
本站是工控技术交流站点,论坛内容均为网络收集或会员所发表,并不代表本站立场,会员拥有该内容的所有权力及责任!
本站内容如有侵犯您的版权,请按下面方式联系本站管理员,我们将及时删除处理
管理员:冰糖 QQ:5483695(请直击主题), Mail:admin#ziwai.net(#改成@) 其它非本人.
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论!

QQ|Archiver|手机版|小黑屋|紫外工控论坛. ( 苏ICP备11032118号-1 )

GMT+8, 2024-5-14 15:47 , Processed in 0.406247 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表