CRC32校验算法C语言版(查表法)

原创 2016年05月16日 17:20:27

最近用到CRC校验算法,就找了些资料,学习了一下,网上关于CRC32的资料也多,但感觉不是很完整,或者太高深。

CRC算法查表法很常见,但表是怎么来的,有些资料说得不很清楚。

我来说一下我的看法:

1.CRC校验变化太多,有CRC4/5/6/7/8/16/32,每一种的多项式也有很多种变化,并不是一成不变的;

2.输入输出方式也有区别,有一些初始值是0,有一些初始值是0xFFFFFFFF,有一些直接返回,有一些异或返回。

因此,CRC校验很难用一个代码兼容全部,只能根据项目需要修改相关参数了。


计算方法:

1.先要知道多项式是什么样子,以这个IEEE802.3标准CRC32多项式为例:x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x+ 1

2.转换成一个值(这个值的命名我不知道啊)

  x32  则对应32bit = 1, x26 则对应26bit=1,得出一个值:(1<<32)|(1<<26)|(1<<23)|(1<<22)|...|(1<<1)|(1)=0x104C11DB7,对于CRC32取低32位,则=0x4C11DB7

3.用这个值通过一定方法生成长度为256的码表,对于CRC32表内每个元素都为32bit.

4.用一定的方法查表得出CRC32值。


好了,可以贴代码了:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


static uint32_t table[256];


//位逆转
static uint32_t bitrev(uint32_t input, int bw)
{
    int i;
    uint32_t var;
    var = 0;
    for(i=0; i<bw; i++)
    {
        if(input & 0x01)
        {
            var |= 1<<(bw - 1 - i);
        }
        input >>= 1;
    }
    return var;
}


//码表生成
void crc32_init(uint32_t poly)
{
    int i;
    int j;
    uint32_t c;


    poly = bitrev(poly, 32);
    for(i=0; i<256; i++)
    {
        c = i;
        for (j=0; j<8; j++)
        {
            c = (c & 1) ? (poly ^ (c >> 1)) : (c >> 1);
        }
        table[i] = c;
    }
}


//计算CRC
uint32_t crc32(uint32_t crc, void* input, int len)
{
    int i;
    uint8_t index;
    uint8_t *p;
    p = (uint8_t*)input;
    for(i=0; i<len; i++)
    {
        index = (*p ^ crc);
        crc = (crc >> 8) ^ table[index];
        p++;
    }
    return crc;
}


//测试用例
void main(void)
{
    uint32_t crc;
    crc32_init(0x4C11DB7);
    crc = crc32(0xFFFFFFFF, "1234567890", 10);
    printf("CRC32 = 0x%08X\n", crc ^ 0xFFFFFFFF);
    system("pause");
}

2017.11.07更新代码: 由于原代码使用unsigned long类型,在64位环境下是64位数据类型,会出现计算结果不正确,因此将其替换为uint32_t类型;


计算结果:

CRC32=0x261DAEE5




版权声明:本文为博主原创文章,未经博主允许不得转载。

CRC查找表法推导及代码实现比较

2018/02/08 再次更新———————————————————————————————————————————本次更新的目的是主要进行一次再排版,顺畅文章的思路。同时鉴于一些网友私信问我的一些问...
  • huang_shiyang
  • huang_shiyang
  • 2016年03月13日 23:36
  • 7894

查表法计算CRC校验码(代码)

如果您不想将一大堆码表复制到您的代码中,可以使用动态生成码表(不过是给256个数字进行CRC计算而已)。下面是生成CRC-32码表的代码(C/C++语言):/*********************...
  • leibniz_zsu
  • leibniz_zsu
  • 2007年05月17日 17:40
  • 6343

CRC32查表法算法实现

CRC参数模型:   Name : "CRC-32"   Width : 32   Poly : 04C11DB7   Init : FFFFFFFF   RefIn : True   R...
  • nh5431313
  • nh5431313
  • 2017年05月16日 15:03
  • 807

CRC校验原理及查表码表由来

CRC校验是编程中使用比较多的一种检验方式,包括CRC8, CRC16, CRC32校验等。校验长度越长,校验所需要的时间越久。为了缩短计算时间,CRC校验又分为直接计算法和查表计算法。 直接计算是一...
  • watterwu
  • watterwu
  • 2017年01月19日 13:40
  • 2452

CRC8查表法中表的具体计算过程

最近看CRC比较多,在翻译完一个英语文档后感觉对CRC的原理有了比较深入的了解,在理解原理后,进入CRC算法的实际应用,当我在网上查找CRC8资料时,看见最多的是这段代码: /************...
  • u010464679
  • u010464679
  • 2016年09月25日 20:11
  • 3628

CRC32查表法

#include windows.h> #include stdio.h> void PrintCrcTable() {     //Poly = 0xedb88320 WinRAR Po...
  • rice19
  • rice19
  • 2014年07月09日 20:50
  • 746

CRC32校验码算法完全版

  • 2018年02月05日 15:46
  • 4KB
  • 下载

CRC算法(直接计算法和查表法)

CRC算法是在通讯领域广泛采用的校验算法。原理我就不说了,这里说一下简单的程序实现。以下均采用CRC多项式为0x1021即: g(x) = x16+x12+x5+x0;CRC的基本原理就不说了,那个...
  • ywb201314
  • ywb201314
  • 2016年08月08日 09:30
  • 7070

深入了解crc32算法

 由于项目需要,解决一个流媒体文件的crc32校验码。网上查了很多的资料,发现了此校验码和生成多项式以及算法本身都有关系。对于不同类型的文件所使用的多项式以及算法不同,对于不同的生成多项式所生成的cr...
  • isadream
  • isadream
  • 2008年01月30日 11:52
  • 11858

C语言实现CRC32算法

static const unsigned int crc32tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076...
  • gongmin856
  • gongmin856
  • 2017年08月11日 17:37
  • 564
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CRC32校验算法C语言版(查表法)
举报原因:
原因补充:

(最多只允许输入30个字)