#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_u32 dataLen = sizeof(tx_data) – 4;
   
    
    
    int sum = 256;
   
    
    
    int i = 0;
   
   
   
   //生成普通表,用于直接计算的表
   
   
   
   gen_direct_table(Table1);
   
   
   
   printf(“Table1 :\n”);
   
   
   
   for (i = 0; i < sum; i++)
   
   
   
   {
   
   
   
   if (i<16)
   
   
   
   printf(“%08x “, Table1[i]);
   
   
   
   }
   
   
   
   printf(“\n\n”);
   
   
   //生成翻转表,是官方推荐的,故称其为normal_table
   
   
   
   gen_normal_table(Table2);
   
   
   
   printf(“Table2 :\n”);
   
   
   
   for (i = 0; i < sum; i++)
   
   
   
   {
   
   
   
   if (i<16)
   
   
   
   printf(“%08x “, Table2[i]);
   
   
   
   }
   
   
   
   printf(“\n\n”);
   
   
   printf(“dataLen = %d\n”, dataLen);//打印数据长度,应该是60字节。
   
    
    
    //计算并打印出CRC32校验码,应该是0x13f56b8b
   
//按照bit进行校验,最慢
   
   
   printf(“Slow CRC by bit          : %08x\n”, crc32_bit(data, dataLen, 0x04c11db7));
   
   
   
   //使用普通表,非官方,很慢
   
   
   
   printf(“Direct Table  ref + xor  : %08x\n”, DIRECT_TABLE_CRC(data, dataLen, Table1));
   
   
   
   //使用翻转表,官方推荐的,很快
   
   
   
   printf(“Reverse Table  ref + xor : %08x\n”, Reverse_Table_CRC(data, dataLen, Table2));
   
   
   system(“pause”);
   
   
   
   return 0;
   
   }
  
 
