CRC-16算法的C语言实现(图文)

 先提供一些资料,本文使用的是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:%#x\n",temp);     
    }
}    

 要验证之前的例子,先将代码做一些修改,由于在编程之前就想到要适应不同的数据位数和生成多项式,这里的修改就很容易,只需修改宏定义,如下

#define N 2
#define GEN_P    0x8005

结果:

结果与之前分析的表格相符 此处高字节在前低字节在后

不过CRC应该是高字节在后低字节在前,这应该是很好改的。

 

转载于:https://www.cnblogs.com/liutogo/p/3633426.html

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值