先提供一些资料,本文使用的是CRC-16、CRC-CCITT或是任何自定义的CRC-16生成多项式
标准CRC生成多项式名称生成多项式 简记式 标准引用CRC-4 x4+x+1 0x3ITU G.704 CRC-8 x8+x5+x4+1 0x31 CRC-8 x8+x2+x1+1 0x07 CRC-8 x8+x6+x4+x3+x2+x1 0x5E CRC-12 x12+x11+x3+x+1 80F CRC-16 x16+x15+x2+1 0x8005IBM SDLC CRC16-CCITT x16+x12+x5+1 0x1021ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS CRC-32 x32+x26+x23+...+x2+x+1 0x04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS CRC-32c x32+x28+x27+...+x8+x6+1 0x1EDC6F41SCTP先看一个CRC-16校验的例子了解CRC校验码是怎样生成的,待校验数据0xa743,此处使用的简记式为CRC-16 0x8005
以下就是我写的代码和流程图,代码在VC6.0环境下测试通过,不过由于scanf("%x",B)经过测试最多只能存4字节16进制数,所以,只有在N<=4的情况下正常,此问题正在寻找解决方案中。
#include<stdio.h>#define N 4#define U16_MSB(x) ((x)&0x8000)#define GEN_P 0x1021 //CRC-CCITT简记式,简记式中忽略最高位1,可换为CRC-16简记式0x8005或任意自定义简记式#define MASK(x) (1<<(x)) typedef unsigned char uint8;typedef unsigned short uint16;main(){ uint8 B[N]; uint8 i,j,cnt,temp_msb; uint16 temp; while(1) { cnt=0; scanf("%x",B); //经测试,%x对应只能存32bit数据,小端存储,“高高低低” temp=B[N-1]; temp=temp<<8; temp+=B[N-2]; while(1) { if(cnt==N*8) break; temp_msb=!!U16_MSB(temp); //取两次反转化为布尔类型 i=cnt%8; j=cnt/8; temp=temp<<1; cnt++; if((N-2-1-j)>=0 && B[N-2-1-j] & MASK(8-1-i)) temp++; if(temp_msb) temp^=GEN_P; } printf("CRC:%#xn",temp); }}要验证之前的例子,先将代码做一些修改,由于在编程之前就想到要适应不同的数据位数和生成多项式,这里的修改就很容易,只需修改宏定义,如下
#define N 2#define GEN_P 0x8005结果:
结果与之前分析的表格相符 此处高字节在前低字节在后
不过CRC应该是高字节在后低字节在前,这应该是很好改的。
转载于:https://www.cnblogs.com/liutogo/p/3633426.html