c++计算 char数组CRC算法

!!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!!

作者:mohist

 

我使用的OS:win7。

我使用的开发环境:VS2010 + sp1 

算法源码:

 

  1 unsigned int create_crc_2(unsigned char *parr, unsigned int parr_len)
  2 {
  3     unsigned char *pbuf = NULL;
  4 
  5     // 数据长度为奇数,在数据前补0
  6     if (1 == parr_len % 2)
  7     {
  8         parr_len    += 1;
  9         pbuf        = new(std::nothrow) unsigned char[parr_len];
 10 
 11         memset(pbuf, 0, parr_len);
 12         memcpy(&pbuf[1], parr, parr_len - 1);
 13     }
 14     // 数据长度为偶数,原样复制数据
 15     else
 16     {
 17         pbuf    = new(std::nothrow) unsigned char[parr_len];
 18         memcpy(pbuf, parr, parr_len);
 19     }
 20     
 21     // 申请空间失败
 22     if (NULL == pbuf)
 23     {
 24         return 0;
 25     }
 26 
 27     // CRC为用来移位的32位数据结构,ploy为32位的生成多项式
 28     unsigned long crc = 0, ploy = 0;
 29     // CRC余数值
 30     unsigned int crc_code   = 0;
 31     int i = 0, j = 0, k = 0;
 32 
 33     // crc = 0xFFFF0000
 34     // crc校验初始值为0 
 35     crc     = 0;    
 36     ploy    = 0x80000000;
 37     // 求得32位的生成多项式
 38     ploy    = ploy ^ ((unsigned long)PLOYNOMAL << 15);
 39 
 40     // for (i = 0; i < 2; i++) 实现编码前预置移位寄存器全为1
 41     // 先讲数据项的前16位放入crc中
 42     crc     = ((unsigned long)pbuf[0] << 24) ^ ((unsigned long)pbuf[1] << 16);
 43     
 44     // 该循环实现数据的移位,计算CRC余数
 45     for (i = 2; i < (int)parr_len + 1; i += 2)
 46     {
 47         // 判断pbuf数据项是否移位完毕
 48         if (i < (int)parr_len)
 49         {
 50             // 如果没有移位完毕,则移入pbuf[i]、pbuf[i+1]
 51             crc = crc ^ ((unsigned long)pbuf[i] << 8) ^ ((unsigned long)pbuf[i + 1]); 
 52         }
 53         // 移位完毕,则移入0000 到 CRC的低16位
 54         else
 55         {
 56             // 由于必须从数据项的第一位为“1”的位开始移位,必须要舍去数据项第一位为“1”的位置前所有的0
 57             crc = crc & 0xFFFF0000;
 58         }
 59 
 60 
 61         if (2 == i)
 62         {
 63             // 舍0
 64             while ( !(crc & 0x80000000)  )
 65             {
 66                 crc = crc << 1;
 67                 // K为舍去的0的个数
 68                 k = k + 1;
 69 
 70                 if (0 == crc)
 71                     break;
 72             }
 73 
 74             // 由于舍去K个0, 因此只需进行16-K次移位
 75             for (j = 0; j < (16 - k); j ++)
 76             {
 77                 // 判断移出的是否为1
 78                 if (crc & 0x80000000)
 79                     crc = ((crc ^ ploy) << 1);
 80                 else
 81                     crc = crc << 1;
 82             }
 83         }
 84         else
 85         {
 86             for (j = 0; j < 16; j ++)
 87             {
 88                  // 判断移出的是否为1
 89                 if (crc & 0x80000000)
 90                     crc = ((crc ^ ploy) << 1);
 91                 else
 92                     crc = crc << 1;
 93             }
 94         }
 95     }
 96 
 97     crc_code    = (unsigned int)(crc >> 16);
 98 
 99     // 清除缓冲
100     delete [] pbuf;
101     pbuf = NULL;
102 
103     // 返回计算结果
104     return crc_code;
105 }

 

 

 

posted @ 2019-06-26 12:02  mohist  阅读(1258)  评论(0编辑  收藏  举报