CRC32校驗算法C語言版(查表法)


最近用到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值。


好了,可以貼代碼了:

/*
* CRC校驗算法,查表法
* <kerndev@foxmail.com>
*/
#include "crc.h"

static unsigned long table[256];

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

//碼表生成
//如:X32+X26+...X1+1,poly=(1<<26)|...|(1<<1)|(1<<0)
void crc32_init(unsigned long poly)
{
	int i;
	int j;
	unsigned long c;
	
	poly=bitrev(poly,32);
	for(i=0; i<256; i++)
	{
		c = i;
		for (j=0; j<8; j++)
		{
			if(c&1)
			{
				c=poly^(c>>1);
			}
			else
			{
				c=c>>1;
			}
		}
		table[i] = c;
	}
}

unsigned long crc32(unsigned long crc, void* input, int len)
{
	int i;
	unsigned char index;
	unsigned char* pch;
	pch = (unsigned char*)input;
	for(i=0;i<len;i++)
	{
		index = (unsigned char)(crc^*pch);
		crc = (crc>>8)^table[index];
		pch++;
	}
	return crc;
}



測試用例:

void main(void)
{
	unsigned long crc;
	crc32_init(0x4C11DB7,table);

	crc = 0xFFFFFFFF;
	crc=crc32(crc,"1234567890",10);
	crc ^= 0xFFFFFFFF;
	printf("CRC32=%08X\n",crc);
	system("pause");
}

計算結果:

CRC32=0x261DAEE5






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM