C语言编写通用crc校验函数

        不同的CRC编写函数,重点差异就在多项式公式,  crc初始值, 结果异或值,  输入翻转,  输出翻转这5个参数的不同。

  • 定义结构图
typedef struct
{
   u32 poly;            //多项式
   u32 InitValue;       //初始值
   u32 xor;             //结果异或值
   BOOL InputReverse;   //输入翻转
   BOOL OutputReverse;  //输出翻转
}S_CRC;
  • 定义crc校验的变量
//const S_CRC 变量              = {多项式公式,  crc初始值, 结果异或值,  输入翻转,  输出翻转}
const S_CRC crc_8               = {0x07,        0x00,       0x00,       FALSE,  FALSE}; //0x07 - x8+x2+x1+1
const S_CRC crc_8_ITU           = {0x07,        0x00,       0x55,       FALSE,  FALSE};
const S_CRC crc_8_ROHC          = {0x07,        0xff,       0x00,       TRUE,   TRUE};
const S_CRC crc_8_MAXIM         = {0x31,        0x00,       0x00,       TRUE,   TRUE};  //0x31 - x8+x4+x3+1
 
const S_CRC crc_16_IBM          = {0x8005,      0x0000,     0x0000,     TRUE,   TRUE};  //0x8005 - x16+x15+x2+1
const S_CRC crc_16_MAXIM        = {0x8005,      0x0000,     0xffff,     TRUE,   TRUE};
const S_CRC crc_16_USB          = {0x8005,      0xffff,     0xffff,     TRUE,   TRUE};
const S_CRC crc_16_MODBUS       = {0x8005,      0xffff,     0x0000,     TRUE,   TRUE};
const S_CRC crc_16_CCITT        = {0x1021,      0x0000,     0x0000,     TRUE,   TRUE};  //0x1021 - x16+x12+x5+1
const S_CRC crc_16_CCITT_FALSE  = {0x1021,      0xffff,     0x0000,     FALSE,  FALSE};
const S_CRC crc_16_X5           = {0x1021,      0xffff,     0xffff,     TRUE,   TRUE};
const S_CRC crc_16_XMODEM       = {0x1021,      0x0000,     0x0000,     FALSE,  FALSE};
const S_CRC crc_16_DNP          = {0x3d65,      0x0000,     0xffff,     TRUE,   TRUE};  //0x3d65 - x16+x13+x12+x11+x10+x8+x6+x5+x2+1
 
const S_CRC crc_32              = {0x04c11db7,  0xffffffff, 0xffffffff, TRUE,   TRUE};
const S_CRC crc_32_MPEG2        = {0x04c11db7,  0xffffffff, 0x00000000, FALSE,  FALSE};
  •  翻转函数
/*****************************************************************************
*function name: reverse
*function:      字节反转,如1100 0101 反转后为1010 0011;1100 0101 1011 1111 反转后为1111 1101 1010 0011
*input:         data    -待反转的数据指针;
*               bit     -反转位数;
*output:        返回反转后的数据
******************************************************************************/
static u32 reverse(u32 data, u8 bit)
{ 
    u8 i;
    u32 temp = 0;
    u8 bitlen = bit;
    for(i = 0; i < bitlen; i++)	
        temp |= ((data>>i) & 0x01) << (bitlen-1-i);

    return temp;
}
  • 通用crc校验函数
/*****************************************************************************
*function name: crc
*function:      通用CRC校验,8位、16位、32位校验通用,根据type和mode来选择具体的crc选项
*input:         addr    -数据首地址;
*               num     -数据长度(字节);
*               type    -CRC的算法类型
*               bit     -crc校验位数
*output:        32位校验值,bit位数数据有效
******************************************************************************/
u32 crc(u8 *addr, int num, S_CRC type, u8 bit)  
{  
    u8 i;  
    u8 data;
    u8 offset = bit - 8;                            //高八位 位移数
    u32 maxbit = 1 << (bit-1);                      //对应位数的最高位为1
    u32 crc = type.InitValue;					    //初始值
    for (; num > 0; num--)               
    {  
        data = *addr++;
        if(type.InputReverse == TRUE)
            data = reverse(data, M_CRC_8);			//字节反转
        crc = crc ^ (data << offset);				//与crc初始值高8位异或 
        for (i = 0; i < 8; i++)					    //循环8位 
        {  
            if (crc & maxbit)				        //左移移出的位为1,左移后与多项式异或
                crc = (crc << 1) ^ type.poly;    
            else                                    //否则直接左移
                crc <<= 1;                  
        }
    }
    if(type.OutputReverse == TRUE)                  //满足条件,反转
        crc = reverse(crc, bit);
    
    crc = crc^type.xor;	                            //最后返与结果异或值异或

    //0xffffffff默认int型,位移操作要小于32位
    if (bit < M_CRC_32)
        crc &= ~(0xffffffff << bit);

    return(crc);                                    //返回最终校验值
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值