关于crc随笔

首先是crc的计算过程
//计算CRC
  1.先要知道多项式是什么样子,
    以这个IEEE802.3标准CRC32多项式为例:x32 + x26 + x23 + x22 + x16 + x12 + x11
  + x10 + x8 + x7 + x5 + x4 + x2 + x+ 1
  2.转换成一个值 (通过这个初值可以生成crc多项式对应的数组表)
    x32  则对应32bit = 1, x26
  则对应26bit=1,得出一个值:(1<<32)|(1<<26)|(1<<23)|(1<<22)|...|(1<<1)|(1)=0x104C11DB7,
  对于CRC32取低32位,则=0x4C11DB7
  3.用这个值通过一定方法生成长度为256的码表,对于CRC32表内每个元素都为32bit.
  4.用一定的方法查表得出CRC32值。

 

一下举两个例子, 例子1:

/* 
多项式 c(x) = x^24+ x^23+ x^6+ x^5+ x + 1 */

二进制 0000 0000 0000 0000 0000 0000 0000 0000
      0000 0001
                1000 0000
                          0000 0000
                                    0110 0011
计算初值:0x800063
crc24初值(0~23bit) = 0x000063
*/

接下来是使用公式计算:

static uint32_t table[256];

//位逆转
static uint32_t bitrev(uint32_t input, int bw) {
  int i;
  uint32_t var;
  var = 0;
  for (i = 0; i < bw; i++) {
    if (input & 0x01) {
      var |= 1 << (bw - 1 - i);
    }
    input >>= 1;
  }
  return var;
}

void crc24_init(uint32_t poly) {
  int i;
  int j;
  uint32_t c;

  poly = bitrev(poly, 24) & 0x00FFFFFF;
  printf("poly:%08x\n",poly);
  for (i = 0; i < 256; i++) {
    c = i;
    for (j = 0; j < 8; j++) {
      c = (c & 1) ? (poly ^ (c >> 1)) : (c >> 1);
    }
    table[i] = c;
    if ((i + 1) % 8 == 0) {
      printf(" 0x%08x\n", c);
    } else {
      printf(" 0x%08x", c);
    }
  }
}


uint32_t crc24(uint32_t crc, void* input, int len) {
  int i;
  uint8_t index;
  uint8_t* p;
  p = (uint8_t*)input;
  for (i = 0; i < len; i++) {
    index = (*p ^ crc);
    crc = (crc >> 8) ^ table[index];
    p++;
  }
  return crc & 0x00FFFFFF;
}

调用方法:

 crc24_init(0x800063);/* 生成表 */
 crc = crc24(0x00FFFFFF, data, 10);
 printf("CRC24_2 = 0x%08X\n", crc);

例子2(crc32):

/*
 IEEE802.3标准CRC32多项式多项式 :  x32 + x26 + x23 + x22 + x16 + x12 + x11
  + x10 + x8 + x7 + x5 + x4 + x2 + x+ 1

CRC32取低32位,则:
初始值=0x4C11DB7

*/
static uint32_t table[256];
static uint32_t bitrev(uint32_t input, int bw) {
  int i;
  uint32_t var;
  var = 0;
  for (i = 0; i < bw; i++) {
    if (input & 0x01) {
      var |= 1 << (bw - 1 - i);
    }
    input >>= 1;
  }
  return var;
}
void crc32_init(uint32_t poly) {
  int i;
  int j;
  uint32_t c;

  poly = bitrev(poly, 32);
  for (i = 0; i < 256; i++) {
    c = i;
    for (j = 0; j < 8; j++) {
      c = (c & 1) ? (poly ^ (c >> 1)) : (c >> 1);
    }
    table[i] = c;
    if ((i + 1) % 8 == 0) {
      printf(" 0x%08x\n", c);
    } else {
      printf(" 0x%08x", c);
    }
  }
}

uint32_t crc32(uint32_t crc, void* input, int len) {
  int i;
  uint8_t index;
  uint8_t* p;
  p = (uint8_t*)input;
  for (i = 0; i < len; i++) {
    index = (*p ^ crc);
    crc = (crc >> 8) ^ table[index];
    p++;
  }
  return crc ^ 0xFFFFFFFF; /* 正常的计算都是直接取 return crc & 0x00FFFFFF; 这个是协议处理用比较特殊,一般用法直接用return crc & 0x00FFFFFF;即可*/
}

调用同crc24计算:

 

  crc32_init(0x4C11DB7);/* 生成表 */
  crc = crc32(initial_value, data, 10);
  printf("CRC32_2 = 0x%08X\n", crc);

测试源码附件: 点我去下载

如不能下载留言邮箱发送.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值