イーサネットフレームFCS検査コードCRC 32の3つの実現方法
3つの実装方法が提供される.
方法1:ビットごとにCRC 32検査コードを計算する.
方法2:非反転のルックアップテーブルを用いて高速計算を行い、バイトでCRC 32チェックコードを計算する.しかし、計算中にビット反転操作があり、計算速度が遅い.
方法3:反転したルックアップテーブルを用いて高速計算を行い、バイトでCRCチェックコードを計算する.スピードがきわめて速い.
方法1:ビットごとにCRC 32検査コードを計算する.
方法2:非反転のルックアップテーブルを用いて高速計算を行い、バイトでCRC 32チェックコードを計算する.しかし、計算中にビット反転操作があり、計算速度が遅い.
方法3:反転したルックアップテーブルを用いて高速計算を行い、バイトでCRCチェックコードを計算する.スピードがきわめて速い.
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#define alt_8 char
#define alt_u8 unsigned char
#define alt_32 int
#define alt_u32 unsigned int
#define alt_64 long long
#define alt_u64 unsigned long long
//
alt_u64 Reflect(alt_u64 ref,alt_u8 ch)
{
int i;
alt_u64 value = 0;
for( i = 1; i < ( ch + 1 ); i++ )
{
if( ref & 1 )
value |= 1 << ( ch - i );
ref >>= 1;
}
return value;
}
// CRC32
#define poly 0x04C11DB7
// CRC32
#define upoly 0xEDB88320
alt_u32 crc32_bit(alt_u8 *ptr, alt_u32 len, alt_u32 gx)
{
alt_u8 i;
alt_u32 crc = 0xffffffff;
while( len-- )
{
for( i = 1; i != 0; i <<= 1 )
{
if( ( crc & 0x80000000 ) != 0 )
{
crc <<= 1;
crc ^= gx;
}
else
crc <<= 1;
if( ( *ptr & i ) != 0 )
crc ^= gx;
}
ptr++;
}
return ( Reflect(crc,32) ^ 0xffffffff );
}
alt_u32 Table1[256];
alt_u32 Table2[256];
// CRC32 , 04C11DB7
void gen_direct_table(alt_u32 *table)
{
alt_u32 gx = 0x04c11db7;
unsigned long i32, j32;
unsigned long nData32;
unsigned long nAccum32;
for ( i32 = 0; i32 < 256; i32++ )
{
nData32 = ( unsigned long )( i32 << 24 );
nAccum32 = 0;
for ( j32 = 0; j32 < 8; j32++ )
{
if ( ( nData32 ^ nAccum32 ) & 0x80000000 )
nAccum32 = ( nAccum32 << 1 ) ^ gx;
else
nAccum32 <<= 1;
nData32 <<= 1;
}
table[i32] = nAccum32;
}
}
// CRC32 77073096
void gen_normal_table(alt_u32 *table)
{
alt_u32 gx = 0x04c11db7;
alt_u32 temp,crc;
for(int i = 0; i <= 0xFF; i++)
{
temp=Reflect(i, 8);
table[i]= temp<< 24;
for (int j = 0; j < 8; j++)
{
unsigned long int t1,t2;
unsigned long int flag=table[i]&0x80000000;
t1=(table[i] << 1);
if(flag==0)
t2=0;
else
t2=gx;
table[i] =t1^t2 ;
}
crc=table[i];
table[i] = Reflect(table[i], 32);
}
}
alt_u32 DIRECT_TABLE_CRC(alt_u8 *ptr,int len, alt_u32 * table)
{
alt_u32 crc = 0xffffffff;
alt_u8 *p= ptr;
int i;
for ( i = 0; i < len; i++ )
crc = ( crc << 8 ) ^ table[( crc >> 24 ) ^ (alt_u8)Reflect((*(p+i)), 8)];
return ~(alt_u32)Reflect(crc, 32) ;
}
alt_u32 Reverse_Table_CRC(alt_u8 *data, alt_32 len, alt_u32 * table)
{
alt_u32 crc = 0xffffffff;
alt_u8 *p = data;
int i;
for(i=0; i <len; i++)
crc = table[( crc ^( *(p+i)) ) & 0xff] ^ (crc >> 8);
return ~crc ;
}
// 。 8b 6b f5 13 FCS , CRC32
alt_u8 tx_data[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, //8
0x29, 0x00, 0xb5, 0xfa, 0x08, 0x06, 0x00, 0x01, //15
0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x1f, //24
0x29, 0x00, 0xb5, 0xfa, 0xac, 0x15, 0x0e, 0xd9, //32
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x15, //40
0x0e, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //48
0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //56
0x00, 0x00, 0x00, 0x00, 0x8b, 0x6b, 0xf5, 0x13 //64
};
int main()
{
alt_u8 *data = tx_data;
alt_u8 dataLen = sizeof(tx_data) -4;
int sum = 256;
int i = 0;
// ,
gen_direct_table(Table1);
printf("Table1 :
");
for( i = 0; i < sum; i++)
{
if(i<16)
printf("%08x ",Table1[i]);
}
printf("
");
// , , normal_table
gen_normal_table(Table2);
printf("Table2 :
");
for( i = 0; i < sum; i++)
{
if(i<16)
printf("%08x ",Table2[i]);
}
printf("
");
printf("dataLen = %d
",dataLen);// , 60 。
// CRC32 , 0x13f56b8b
// bit ,
printf("Slow CRC by bit : %08x
",crc32_bit( data, dataLen, 0x04c11db7 ));
// , ,
printf("Direct Table ref + xor : %08x
",DIRECT_TABLE_CRC (data,dataLen,Table1));
// , ,
printf("Reverse Table ref + xor : %08x
",Reverse_Table_CRC(data,dataLen,Table2));
system("pause");
return 0;
}
回転: http://blog.csdn.net/delacroix_xu/article/details/7589333