CRC32教程_个人理解

一、简介:

我用的是直接计算法,非查表法。直接计算更符合我的项目要求,我是使用在STM32单片机上的用的是KEIL。按道理说跟平台无关,整个用的是C语言编写。在网上也有很多对CRC的讲解,我这里就不班门弄斧了,我也是刚学的,很多网站教程都很详细的讲解了CRC的原理和方法,但是比较少有一个总的总结,在这里我只写我的实现过程,或许能帮到刚学习的朋友,顺便记录一下。
这里推荐一个挺不错的讲解网站看完网站的讲解,再看剩下的流程就明白了。

CRC32为例详细解析(菜鸟至老鸟进阶)

二、步骤:

需要计算的数据:data
POLY:多项式
INIT:初始值

XOROUT  :结果异或值

1、对数据data倒置(跟第四步的倒置有区别)


这是是针对的每个字节,而不是整个数据,然后赋回给data
例如:
00101011,10110100,00100101,10000011
                                                                    倒置:
11010100,00101101,10100100,11000001

2、data = data ^ 初始值 INIT

(一般是0xFFFFFFFF,或者0x00000000,也可以自定义)

3、这里就开始计算

判断data最高位为1还是0,
1:data = data^POLY
0:不处理
然后data左移一位再重复执行步骤3,直到得到一个等于或小于 多项式(其实就是按照数据长度一般都是移多少次,8bit:8次,32bit:32次)

4、输出结果处理

data = data ^ 结果异或值 XOROUT (一般是0xFFFFFFFF,或者0x00000000,也可以自定义)

5、倒置整个结果data,(跟第一步不同)

这个是倒置整个数据。

例如:

00101011,10110100,00100101,10000011

倒置:

11000001,10100100,00101101,11010100

6、得到的 最终数据就是 CRC32 的值

这里附上几个CRC校验的网站:

ip33.com

On-line CRC calculation and free library

步骤计算结果:

三、代码分享

1、这是需要用到的代码倒置函数

/*
功	能:倒置数据  :例如10110010,倒置后:01001101
参	数:datar:需倒置的数据
        dlen:倒置数据的长度 8/16/32
返回值:倒置后的数据
*/
unsigned int zRCR_BitReverse(unsigned int datar,unsigned char dlen)  //倒序数据 8/16/32
{
   unsigned int Rvalue=0;
   unsigned char i;
    for(i=0;i<dlen;i++)   //倒置数据
    {
        Rvalue |=((datar>>i)&0x00000001);
        if(i>=(dlen-1)) break;
        Rvalue<<=1;
    }
   return Rvalue;
}

2、CRC计算函数(输入数据为8bit)

/*
功	能:计算CRC32的值
参	数:*data:需计算的数据
        len:数据个数
        repeat:是否接着上一次计算,0:开始新的一轮计算,1:接着上次计算
返回值:CRC32的值
*/
unsinged int zCRC_Value;
unsigned int zCRC_GetCRC(unsigned char *data,unsigned int len,unsigned char repeat)
{
    unsigned int i;
    unsigned int value_temp;
    if(repeat == 0)  //是否继续上次的数据校验
        zCRC_Value = 0XFFFFFFFF;//zCRC_State.zCRC_InitValue;
    while(len !=0)
    {
        //开启输入数据反转
        //1、倒置数据,单独倒置每个Byte数据,非整个数据倒置
        value_temp = 0;
        value_temp |= (zRCR_BitReverse(((*data)&0xFF),8));
        value_temp <<=24; // 将数据移动最高位
        data++;
        //2、数据与初始值求或
        zCRC_Value ^= value_temp;      
        for(i=0;i<8;i++)
        {
            if(zCRC_State.zCRC_Value&0x80000000)
            {
                zCRC_Value <<=1;
                zCRC_Value ^=0x4C11DB7;
            }
            else 
                zCRC_Value <<=1;
        }
        len--;
    }
    return zRCR_BitReverse(zCRC_Value^0XFFFFFFFF,32);
}

2、CRC计算函数(输入数据为32bit)

unsinged int zCRC_Value;
unsigned int zCRC_GetCRC(unsigned int *data,unsigned int len,unsigned char repeat)
{
    unsigned int i;
    unsigned int value_temp;
    if(repeat == 0)  //是否继续上次的数据校验
        zCRC_Value = 0XFFFFFFFF;
    while(len !=0)
    {
        //1、倒置数据,单独倒置每个Byte数据,非整个数据倒置:例如:00100101,10000011倒置过来>> 10100100,11000001
        value_temp = 0;
        for(i=0;i<32;)//
        {
            //先将数据右移i位取1Byte,将二进制倒置一下,再往左移i位,保存value_temp
            value_temp |= (zRCR_BitReverse(((*data>>i)&0xFF),8)<<i);
            i+=8;//i每次进位8bit,1Byte
        }
        data++;
        //2、数据与初始值求或
        zCRC_State.zCRC_Value ^= value_temp;      
        for(i=0;i<32;i++)
        {
            if(zzCRC_Value&0x80000000)
            {
                zCRC_Value <<=1;
                zCRC_Value ^=0x4C11DB7;
            }
            else 
                zCRC_Value <<=1;
        }
        len--;
    }
    return zRCR_BitReverse(zCRC_Value^0XFFFFFFFF,32);
}

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值