最近用到CRC校驗(yàn)算法,就找了些資料,學(xué)習(xí)了一下,網(wǎng)上關(guān)于CRC32的資料也多,但感覺不是很完整,或者太高深。 CRC算法查表法很常見,但表是怎么來的,有些資料說得不很清楚。 我來說一下我的看法: 1.CRC校驗(yàn)變化太多,有CRC4/5/6/7/8/16/32,每一種的多項(xiàng)式也有很多種變化,并不是一成不變的; 2.輸入輸出方式也有區(qū)別,有一些初始值是0,有一些初始值是0xFFFFFFFF,有一些直接返回,有一些異或返回。 因此,CRC校驗(yàn)很難用一個(gè)代碼兼容全部,只能根據(jù)項(xiàng)目需要修改相關(guān)參數(shù)了。
計(jì)算方法: 1.先要知道多項(xiàng)式是什么樣子,以這個(gè)IEEE802.3標(biāo)準(zhǔn)CRC32多項(xiàng)式為例:x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x+ 1 2.轉(zhuǎn)換成一個(gè)值(這個(gè)值的命名我不知道?。?/span> x32 則對(duì)應(yīng)32bit = 1, x26 則對(duì)應(yīng)26bit=1,得出一個(gè)值:(1<<32)|(1<<26)|(1<<23)|(1<<22)|...|(1<<1)|(1)=0x104C11DB7,對(duì)于CRC32取低32位,則=0x4C11DB7 3.用這個(gè)值通過一定方法生成長度為256的碼表,對(duì)于CRC32表內(nèi)每個(gè)元素都為32bit. 4.用一定的方法查表得出CRC32值。
好了,可以貼代碼了: - /*
- * CRC校驗(yàn)算法,查表法
- *
- */
- #include 'crc.h'
-
- static unsigned long table[256];
-
- //位逆轉(zhuǎn)
- static unsigned long bitrev(unsigned long input, int bw)
- {
- int i;
- unsigned long var;
- var = 0;
- for(i=0;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
- {
- index = (unsigned char)(crc^*pch);
- crc = (crc>>8)^table[index];
- pch++;
- }
- return crc;
- }
/** CRC校驗(yàn)算法,查表法* */#include 'crc.h'static unsigned long table[256];//位逆轉(zhuǎn)static unsigned long bitrev(unsigned long input, int bw){ int i; unsigned long var; var = 0; for(i=0;i>=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>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');
- }
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');}
計(jì)算結(jié)果: CRC32=0x261DAEE5
|