以太网帧FCS校验码CRC32的三种实现方法

提供了三种实现方法。

方法一:按位计算CRC32校验码。

方法二:使用非翻转的查找表进行快速计算,按字节计算CRC32校验码。但计算过程中有位翻转操作,计算速度慢。

方法三:使用翻转的查找表进行快速计算,按字节计算CRC校验码。速度极快。

 

[cpp]   view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <io.h>  
  4.   
  5.   
  6.   
  7.   
  8. #define alt_8    char  
  9. #define alt_u8   unsigned char  
  10. #define alt_32   int  
  11. #define alt_u32  unsigned int  
  12. #define alt_64   long long  
  13. #define alt_u64  unsigned long long  
  14.   
  15.   
  16. //位翻转函数  
  17. alt_u64 Reflect(alt_u64 ref,alt_u8 ch)  
  18. {     
  19.     int i;  
  20.     alt_u64 value = 0;  
  21.     for( i = 1; i < ( ch + 1 ); i++ )  
  22.     {  
  23.         if( ref & 1 )  
  24.             value |= 1 << ( ch - i );  
  25.         ref >>= 1;  
  26.     }  
  27.     return value;  
  28. }  
  29.   
  30.   
  31. //标准的CRC32多项式  
  32. #define poly  0x04C11DB7  
  33. //翻转的CRC32多项式  
  34. #define upoly 0xEDB88320  
  35.   
  36.   
  37.   
  38. alt_u32 crc32_bit(alt_u8 *ptr, alt_u32 len, alt_u32 gx)  
  39. {  
  40.     alt_u8 i;  
  41.     alt_u32 crc = 0xffffffff;  
  42.     while( len-- )  
  43.     {  
  44.         for( i = 1; i != 0; i <<= 1 )  
  45.         {  
  46.             if( ( crc & 0x80000000 ) != 0 )  
  47.             {  
  48.                 crc <<= 1;  
  49.                 crc ^= gx;  
  50.             }  
  51.             else   
  52.                 crc <<= 1;  
  53.             if( ( *ptr & i ) != 0 )   
  54.                 crc ^= gx;  
  55.         }  
  56.         ptr++;  
  57.     }  
  58.     return ( Reflect(crc,32) ^ 0xffffffff );  
  59. }  
  60.   
  61.   
  62.   
  63.   
  64.   
  65.   
  66. alt_u32 Table1[256];  
  67. alt_u32 Table2[256];  
  68.   
  69.   
  70.   
  71.   
  72.  // 生成CRC32 普通表 , 第二项是04C11DB7  
  73. void gen_direct_table(alt_u32 *table)  
  74. {  
  75.     alt_u32 gx = 0x04c11db7;  
  76.     unsigned long i32, j32;  
  77.     unsigned long nData32;  
  78.     unsigned long nAccum32;  
  79.     for ( i32 = 0; i32 < 256; i32++ )  
  80.     {  
  81.         nData32 = ( unsigned long )( i32 << 24 );  
  82.         nAccum32 = 0;  
  83.         for ( j32 = 0; j32 < 8; j32++ )  
  84.         {  
  85.             if ( ( nData32 ^ nAccum32 ) & 0x80000000 )  
  86.                 nAccum32 = ( nAccum32 << 1 ) ^ gx;  
  87.             else  
  88.                 nAccum32 <<= 1;  
  89.             nData32 <<= 1;  
  90.         }  
  91.         table[i32] = nAccum32;  
  92.     }  
  93. }  
  94.   
  95.   
  96. // 生成CRC32 翻转表 第二项是77073096  
  97. void gen_normal_table(alt_u32 *table)  
  98. {  
  99.     alt_u32 gx = 0x04c11db7;  
  100.     alt_u32 temp,crc;  
  101.     for(int i = 0; i <= 0xFF; i++)   
  102.     {  
  103.         temp=Reflect(i, 8);  
  104.         table[i]= temp<< 24;  
  105.         for (int j = 0; j < 8; j++)  
  106.         {  
  107.             unsigned long int t1,t2;  
  108.             unsigned long int flag=table[i]&0x80000000;  
  109.             t1=(table[i] << 1);  
  110.             if(flag==0)  
  111.             t2=0;  
  112.             else  
  113.             t2=gx;  
  114.             table[i] =t1^t2 ;  
  115.         }  
  116.         crc=table[i];  
  117.         table[i] = Reflect(table[i], 32);  
  118.     }  
  119. }  
  120.   
  121.   
  122.   
  123. alt_u32 DIRECT_TABLE_CRC(alt_u8 *ptr,int len, alt_u32 * table)   
  124. {  
  125.     alt_u32 crc = 0xffffffff;   
  126.     alt_u8 *p= ptr;  
  127.     int i;  
  128.     for ( i = 0; i < len; i++ )  
  129.         crc = ( crc << 8 ) ^ table[( crc >> 24 ) ^ (alt_u8)Reflect((*(p+i)), 8)];  
  130.     return ~(alt_u32)Reflect(crc, 32) ;  
  131. }  
  132.   
  133.   
  134.   
  135.   
  136. alt_u32 Reverse_Table_CRC(alt_u8 *data, alt_32 len, alt_u32 * table)  
  137. {  
  138.     alt_u32 crc = 0xffffffff;    
  139.     alt_u8 *p = data;  
  140.     int i;  
  141.     for(i=0; i <len; i++)  
  142.         crc =  table[( crc ^( *(p+i)) ) & 0xff] ^ (crc >> 8);  
  143.     return  ~crc ;   
  144. }  
  145.   
  146.   
  147.   
  148. //这是一个完整的以太网帧。最后四个字节 8b 6b f5 13是其FCS字段,用于与后面生成的CRC32对照  
  149. alt_u8  tx_data[] = {  
  150.         0xff,   0xff,   0xff,   0xff,   0xff,   0xff,   0x00,   0x1f,   //8  
  151.         0x29,   0x00,   0xb5,   0xfa,   0x08,   0x06,   0x00,   0x01,   //15  
  152.         0x08,   0x00,   0x06,   0x04,   0x00,   0x01,   0x00,   0x1f,   //24  
  153.         0x29,   0x00,   0xb5,   0xfa,   0xac,   0x15,   0x0e,   0xd9,   //32  
  154.         0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0xac,   0x15,   //40  
  155.         0x0e,   0x8e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   //48  
  156.         0x00,   0x00 ,  0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   //56  
  157.         0x00,   0x00,   0x00,   0x00,   0x8b,   0x6b,   0xf5,   0x13    //64  
  158. };  
  159.   
  160.   
  161.   
  162.   
  163. int main()  
  164. {  
  165.     alt_u8 *data = tx_data;  
  166.     alt_u8 dataLen = sizeof(tx_data) -4;  
  167.     
  168.     int sum = 256;  
  169.     int i = 0;  
  170.   
  171.     //生成普通表,用于直接计算的表  
  172.     gen_direct_table(Table1);  
  173.     printf("Table1 :\n");  
  174.     for( i = 0; i < sum; i++)  
  175.     {  
  176.         if(i<16)  
  177.             printf("%08x ",Table1[i]);  
  178.     }  
  179.     printf("\n\n");  
  180.   
  181.   
  182.     //生成翻转表,是官方推荐的,故称其为normal_table  
  183.     gen_normal_table(Table2);  
  184.     printf("Table2 :\n");  
  185.     for( i = 0; i < sum; i++)  
  186.     {  
  187.         if(i<16)  
  188.             printf("%08x ",Table2[i]);  
  189.     }  
  190.     printf("\n\n");  
  191.   
  192.   
  193.   
  194.     printf("dataLen = %d\n",dataLen);//打印数据长度,应该是60字节。  
  195.   
  196.   
  197.   
  198.     //计算并打印出CRC32校验码,应该是0x13f56b8b  
  199.   
  200.     //按照bit进行校验,最慢  
  201.     printf("Slow CRC by bit          : %08x\n",crc32_bit( data, dataLen, 0x04c11db7 ));  
  202.     //使用普通表,非官方,很慢  
  203.     printf("Direct Table  ref + xor  : %08x\n",DIRECT_TABLE_CRC (data,dataLen,Table1));   
  204.     //使用翻转表,官方推荐的,很快  
  205.     printf("Reverse Table  ref + xor : %08x\n",Reverse_Table_CRC(data,dataLen,Table2));   
  206.   
  207.   
  208.     system("pause");      
  209.     return 0;  
  210. }  


转载于:https://www.cnblogs.com/zhs36252625119/p/4287116.html

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值