码迷,mamicode.com
首页 > 其他好文 > 详细

CRC32相关

时间:2015-02-28 00:14:45      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:

CRC即循环冗余校验码(Cyclic Redundancy Check)。

CRC32算法中,这个生成多项式为:
c(x) = 1 + x + x^2 + x^4 + x^5 + x^7 + x^8 + x^10 + x^11 + x^12 + x^16 + x^22 + x^23 + x^26 + x^32。
其对应的数字就为:11101101101110001000001100100000(x^32在实际计算时隐含给出,因此这里没有包含它
的系数),也就是0xEDB88320(多项式对应的数字可能颠倒,颠倒后得到的是0x04C11DB7,其实也是正确的)。 由此可以看出,CRC值也可以看成我们的数据除以一个生成多项式而得到的余数。

容易理解的是位运算

  1. // 以4 byte数据为例  
  2. #define POLY 0x04C11DB7L // CRC32生成多项式  
  3. unsigned int CRC32_1(unsigned int data)  
  4. {  
  5.     unsigned char p[8];  
  6.     memset(p, 0, sizeof(p));  
  7.     memcpy(p, &data, 4);  
  8.     unsigned int reg = 0, idx = 0;  
  9.     for(int i = 0; i < 64; i++)  
  10.     {  
  11.         idx = i/8;  
  12.         int hi = (reg>>31)&0x01; // 取得reg的最高位  
  13.         // 把reg左移1bit,并移入新数据到reg0  
  14.         reg = (reg<<1)| (p[idx]>>7);  
  15.         if(hi) reg = reg^POLY; // hi=1就用reg除以g(x)  
  16.         p[idx]<<=1;  
  17.     }  
  18.     return reg;  

位运算速度慢,扩展到字节为单位

// 以4 byte数据为例
#define POLY 0x04C11DB7L // CRC32生成多项式
unsigned int CRC32_2(unsigned int data)
{
    unsigned char p[8];
    memset(p, 0, sizeof(p));
    memcpy(p, &data, 4);
    unsigned int reg = 0, sum_poly = 0;
    for(int i = 0; i < 8; i++)
    {
        // 计算步骤1
        sum_poly = reg&0xFF000000;
        for(int j = 0; j < 8; j++)
        {
            int hi = sum_poly&0x80000000; // 测试reg最高位
            sum_poly <<= 1;
            if(hi) sum_poly = sum_poly^POLY;
        }
        // 计算步骤2
        reg = (reg<<8)|p[i];
        reg = reg ^ sum_poly;
    }
    return reg;
}
但实际使用的是一种表驱动的方式,

static void init_crc_table(void)
{
    unsigned int c;
    unsigned int i, j;
    
    for (i = 0; i < 256; i++) {
        c = (unsigned int)i;
        for (j = 0; j < 8; j++) {
            if (c & 1)
                c = 0xedb88320L ^ (c >> 1);
            else
                c = c >> 1;
        }
        crc_table[i] = c;
    }
}

/*计算buffer的crc校验码*/
static unsigned int crc32(unsigned int crc,unsigned char *buffer, unsigned int size)
{
    unsigned int i;
    for (i = 0; i < size; i++) {
        crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8);
    }
    return crc ;
}

 

CRC32相关

标签:

原文地址:http://www.cnblogs.com/junka/p/4304489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!