首页 CRC 算法原理及C 语言实现

CRC 算法原理及C 语言实现

举报
开通vip

CRC 算法原理及C 语言实现CRC算法原理及C语言实现摘要本文从理论上推导出CRC算法实现原理,给出三种分别适应不同计算机或微控制器硬件环境的C语言程序。读者更能根据本算法原理,用不同的语言编写出独特风格更加实用的CRC计算程序。关键词CRC算法C语言1引言循环冗余码CRC检验技术广泛应用于测控及通信领域。CRC计算可以靠专用的硬件来实现,但是对于低成本的微控制器系统,在没有硬件支持下实现CRC检验,关键的问题就是如何通过软件来完成CRC计算,也就是CRC算法的问题。这里将提供三种算法,它们稍有不同,一种适用于程序空间十分苛刻但CRC计算速度...

CRC 算法原理及C 语言实现
CRC算法原理及C语言实现摘要本文从理论上推导出CRC算法实现原理,给出三种分别适应不同计算机或微控制器硬件环境的C语言程序。读者更能根据本算法原理,用不同的语言编写出独特风格更加实用的CRC计算程序。关键词CRC算法C语言1引言循环冗余码CRC检验技术广泛应用于测控及通信领域。CRC计算可以靠专用的硬件来实现,但是对于低成本的微控制器系统,在没有硬件支持下实现CRC检验,关键的问题就是如何通过软件来完成CRC计算,也就是CRC算法的问题。这里将提供三种算法,它们稍有不同,一种适用于程序空间十分苛刻但CRC计算速度要求不高的微控制器系统,另一种适用于程序空间较大且CRC计算速度要求较高的计算机或微控制器系统,最后一种是适用于程序空间不太大,且CRC计算速度又不可以太慢的微控制器系统。2CRC简介CRC校验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码)r位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端,则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(既乘以216)后,再除以一个多项式,最后所得到的余数既是CRC码,如式(2-1)式所示,其中B(X)表示n位的二进制序列数,G(X)为多项式,Q(X)为整数,R(X)是余数(既CRC码)。B(X)×216R(X)=Q(X)+(2-1)G(X)G(X)求CRC码所采用模2加减运算法则,既是不带进位和借位的按位加减,这种加减运算实际上就是逻辑上的异或运算,加法和减法等价,乘法和除法运算与普通代数式的乘除法运算是一样,符 合同 劳动合同范本免费下载装修合同范本免费下载租赁合同免费下载房屋买卖合同下载劳务合同范本下载 样的规律。生成CRC码的多项式如下,其中CRC-16和CRC-CCITT产生16位的CRC码,而CRC-32则产生的是32位的CRC码。本文不讨论32位的CRC算法,有兴趣的朋友可以根据本文的思路自己去推导计算方法。16152CRC-16:(美国二进制同步系统中采用)G(X)=X+X+X+116125CRC-CCITT:(由欧洲CCITT推荐)G(X)=X+X+X+132262322161211108CRC-32:G(X)=X+X+X+X+X+X+X+X+X+X7+X5+X4+X2+X1+1接收方将接收到的二进制序列数(包括信息码和CRC码)除以多项式,如果余数为0,则说明传输中无错误发生,否则说明传输有误,关于其原理这里不再多述。用软件计算CRC码时,接收方可以将接收到的信息码求CRC码,比较结果和接收到的CRC码是否相同。3按位计算CRC对于一个二进制序列数可以表示为式(3-1):nn-1B(X)=Bn×2+Bn-1×2+×××+B1×2+B0(3-1)求此二进制序列数的CRC码时,先乘以216后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(3-2)所示:B(X)×216B×216B×216B×216B×216=n×2n+n-1×2n-1+×××+1×2+0(3-2)G(X)G(X)G(X)G(X)G(X)B×216R(X)可以设:n=Q(X)+n(3-3)G(X)nG(X)其中Qn(X)为整数,Rn(X)为16位二进制余数。将式(3-3)代入式(3-2)得:B(X)×216R(X)B×216B×216B×216={Q(X)+n}×2n+n-1×2n-1+×××+1×2+0G(X)nG(X)G(X)G(X)G(X)R(X)×2B×216B×216B×216=Q(X)×2n+{n+n-1}×2n-1+×××+1×2+0(3-4)nG(X)G(X)G(X)G(X)R(X)×2B×216R(X)再设:n+n-1=Q(X)+n-1(3-5)G(X)G(X)n-1G(X)其中Qn-1(X)为整数,Rn-1(X)为16位二进制余数,将式(3-5)代入式(3-4),如上类推,最后得到:B(X)×216R(X)=Q(X)×2n+Q(X)×2n-1+Q(X)×2n-2+×××+Q(X)+0(3-6)G(X)nn-1n-20G(X)根据CRC的定义,很显然,十六位二进制数R0(X)既是我们要求的CRC码。式(3-5)是编程计算CRC的关键,它说明计算本位后的CRC码等于上一位CRC码乘以2后除以多项式,所得的余数再加上本位值除以多项式所得的余数。由此不难理解下面求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,0x1021与多项式有关。unsignedintcal_crc(unsignedchar*ptr,unsignedcharlen){unsignedchari;unsignedintcrc=0;while(len--!=0){for(i=0x80;i!=0;i/=2){if((crc&0x8000)!=0){crc*=2;crc^=0x1021;}/*余式CRC乘以2再求CRC*/elsecrc*=2;if((*ptr&i)!=0)crc^=0x1021;/*再加上本位的CRC*/}ptr++;}return(crc);}按位计算CRC虽然代码简单,所占用的内存比较少,但其最大的缺点就是一位一位地计算会占用很多的处理器处理时间,尤其在高速通讯的场合,这个缺点更是不可容忍。因此下面再介绍一种按字节查表快速计算CRC的方法。4按字节计算CRC不难理解,对于一个二进制序列数可以按字节表示为式(4-1),其中Bn(X)为一个字节(共8位)。8n8(n-1)8B(X)=Bn(X)×2+Bn-1(X)×2+×××+B1(X)×2+B0(X)(4-1)求此二进制序列数的CRC码时,先乘以216后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(4-2)所示:B(X)×216B(X)×216B(X)×216B(X)×216=n×28n+n-1×28(n-1)+×××+0(4-2)G(X)G(X)G(X)G(X)B(X)×216R(X)可以设:n=Q(X)+n(4-3)G(X)nG(X)其中Qn(X)为整数,Rn(X)为16位二进制余数。将式(4-3)代入式(4-2)得:B(X)×216R(X)B(X)×216B(X)×216=[Q(X)+n]×28n+n-1×28(n-1)+×××+0G(X)nG(X)G(X)G(X)R(X)×28B(X)×216B×216=Q(X)×28n+{n+n-1}×28(n-1)+×××+0(4-4)nG(X)G(X)G(X)888因为:Rn(X)×2=[RnH8(X)×2+RnL8(X)]×2168=RnH8(X)×2+RnL8(X)×2(4-5)其中RnH8(X)是Rn(X)的高八位,RnL8(X)是Rn(X)的低八位。将式(4-5)代入式(4-4),经整理后得:B(X)×216R(X)×28[R(X)+B(X)]×216B×216=Q(X)×28n+{nL8+nH8n-1}×28(n-1)+×××+0G(X)nG(X)G(X)G(X)(4-6)R(X)×28[B(X)+B(X)]×216R(X)再设:nL8+nH8n-1=Q(X)+n-1(4-7)G(X)G(X)n-1G(X)其中Qn-1(X)为整数,Rn-1(X)为16位二进制余数。将式(4-7)代入式(4-6),如上类推,最后得:B(X)×216R(X)=Q(X)×28n+Q(X)×28(n-1)+×××+Q(X)+0(4-8)G(X)nn-10G(X)很显然,十六位二进制数R0(X)既是我们要求的CRC码。式(4-7)是编写按字节计算CRC程序的关键,它说明计算本字节后的CRC码等于上一字节余式CRC码的低8位左移8位后,再加上上一字节CRC右移8位(也既取高8位)和本字节之和后所求得的CRC码,如果我们把8位二进制序列数的CRC全部计算出来,放如一个表里,采用查表法,可以大大提高计算速度。由此不难理解下面按字节求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,CRC余式表是按0x11021多项式求出的。unsignedintcal_crc(unsignedchar*ptr,unsignedcharlen){unsignedintcrc;unsignedcharda;unsignedintcrc_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};crc=0;while(len--!=0){da=(uchar)(crc/256);/*以8位二进制数的形式暂存CRC的高8位*/crc<<=8;/*左移8位,相当于CRC的低8位乘以28*/crc^=crc_ta[da^*ptr];/*高8位和当前字节相加后再查表求CRC,再加上以前的CRC*/ptr++;}return(crc);}很显然,按字节求CRC时,由于采用了查表法,大大提高了计算速度。但对于广泛运用的8位微处理器,代码空间有限,对于要求256个CRC余式表(共512字节的内存)已经显得捉襟见肘了,但CRC的计算速度又不可以太慢,因此再介绍下面一种按半字节求CRC的算法。5按半字节计算CRC同样道理,对于一个二进制序列数可以按字节表示为式(5-1),其中Bn(X)为半个字节(共4位)。4n4(n-1)4B(X)=Bn(X)×2+Bn-1(X)×2+×××+B1(X)×2+B0(X)(5-1)求此二进制序列数的CRC码时,先乘以216后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(4-2)所示:B(X)×216B(X)×216B(X)×216B(X)×216=n×24n+n-1×24(n-1)+×××+0(5-2)G(X)G(X)G(X)G(X)B(X)×216R(X)可以设:n=Q(X)+n(5-3)G(X)nG(X)其中Qn(X)为整数,Rn(X)为16位二进制余数。将式(5-3)代入式(5-2)得:B(X)×216R(X)B(X)×216B(X)×216=[Q(X)+n]×24n+n-1×24(n-1)+×××+0G(X)nG(X)G(X)G(X)R(X)×24B(X)×216B×216=Q(X)×24n+{n+n-1}×24(n-1)+×××+0(5-4)nG(X)G(X)G(X)4124因为:Rn(X)×2=[RnH4(X)×2+RnL12(X)]×2164=RnH4(X)×2+RnL12(X)×2(5-5)其中RnH4(X)是Rn(X)的高4位,RnL12(X)是Rn(X)的低12位。将式(5-5)代入式(5-4),经整理后得:B(X)×216R(X)×24[R(X)+B(X)]×216B×216=Q(X)×24n+{nL12+nH4n-1}×24(n-1)+×××+0G(X)nG(X)G(X)G(X)(5-6)R(X)×24[B(X)+B(X)]×216R(X)再设:nL12+nH4n-1=Q(X)+n-1(5-7)G(X)G(X)n-1G(X)其中Qn-1(X)为整数,Rn-1(X)为16位二进制余数。将式(5-7)代入式(5-6),如上类推,最后得:B(X)×216R(X)=Q(X)×24n+Q(X)×24(n-1)+×××+Q(X)+0(5-8)G(X)nn-10G(X)很显然,十六位二进制数R0(X)既是我们要求的CRC码。式(5-7)是编写按字节计算CRC程序的关键,它说明计算本字节后的CRC码等于上一字节CRC码的低12位左移4位后,再加上上一字节余式CRC右移4位(也既取高4位)和本字节之和后所求得的CRC码,如果我们把4位二进制序列数的CRC全部计算出来,放在一个表里,采用查表法,每个字节算两次(半字节算一次),可以在速度和内存空间取得均衡。由此不难理解下面按半字节求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,CRC余式表是按0x11021多项式求出的。unsignedcal_crc(unsignedchar*ptr,unsignedcharlen){unsignedintcrc;unsignedcharda;unsignedintcrc_ta[16]={/*CRC余式表*/0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,}crc=0;while(len--!=0){da=((uchar)(crc/256))/16;/*暂存CRC的高四位*/crc<<=4;/*CRC右移4位,相当于取CRC的低12位)*/crc^=crc_ta[da^(*ptr/16)];/*CRC的高4位和本字节的前半字节相加后查表计算CRC,然后加上上一次CRC的余数*/da=((uchar)(crc/256))/16;/*暂存CRC的高4位*/crc<<=4;/*CRC右移4位,相当于CRC的低12位)*/crc^=crc_ta[da^(*ptr&0x0f)];/*CRC的高4位和本字节的后半字节相加后查表计算CRC,然后再加上上一次CRC的余数*/ptr++;}return(crc);}5结束语以上介绍的三种求CRC的程序,按位求法速度较慢,但占用最小的内存空间;按字节查表求CRC的方法速度较快,但占用较大的内存;按半字节查表求CRC的方法是前两者的均衡,即不会占用太多的内存,同时速度又不至于太慢,比较适合8位小内存的单片机的应用场合。以上所给的C程序可以根据各微处理器编译器的特点作相应的改变,比如把CRC余式表放到程序存储区内等。
本文档为【CRC 算法原理及C 语言实现】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_118577
暂无简介~
格式:pdf
大小:40KB
软件:PDF阅读器
页数:6
分类:互联网
上传时间:2016-12-07
浏览量:21