现在的位置: 首页 > 综合 > 正文

计算CRC的逆(当数据长度等于CRC长度时)

2013年10月09日 ⁄ 综合 ⁄ 共 2165字 ⁄ 字号 评论关闭

 

// Demo_CRC.cpp

#include "stdafx.h"
#include <locale.h>

#include "CRC.h"

// 将一个字节逆序
unsigned char inv_bits(unsigned char c);

int _tmain(int argc, _TCHAR* argv[])
{
 setlocale(LC_ALL,"chs");

 _tprintf(_T("\nCRC逆计算的演示程序\n\n"));

 // 原始数据
 unsigned char data[] = {1,2};
 _tprintf(_T("原始数据: 0x%02X 0x%02X\n"), data[0], data[1]);

 // 初始crc
 unsigned short initCrc = 0;

 // 计算高位在前CRC
 CRC16_H crc_ccitt(0x1021);
 unsigned short crcH = crc_ccitt.do_crcH(initCrc, data, sizeof(data));
 unsigned char crc16_H[2] = {0};
 crc16_H[0] = HIBYTE(crcH);
 crc16_H[1] = LOBYTE(crcH);
 _tprintf(_T("crc_ccitt数据: 0x%02X 0x%02X\n"), crc16_H[0], crc16_H[1]);

 // 验证高位在前CRC, 拉通CRC为0
 unsigned char dataL[] =
 {
  // 原始数据
  data[0], data[1],

  // CRC
  crc16_H[0], crc16_H[1]
 };
 unsigned short crcCheckL = crc_ccitt.do_crcH(initCrc, dataL, sizeof(dataL));

 // 逆运算
 unsigned char inv_data[2] = {inv_bits(crc16_H[1]), inv_bits(crc16_H[0])};

 CRC16_H inv_ccitt(0x0811); // crc_ccitt的逆表达式为0x0811
 unsigned short inv_crcH = inv_ccitt.do_crcH(initCrc, inv_data, sizeof(inv_data));
 unsigned char inv_crc16_H[2] = {0};
 inv_crc16_H[0] = HIBYTE(inv_crcH);
 inv_crc16_H[1] = LOBYTE(inv_crcH);

 // CRC逆计算出的数据
 unsigned char inv_crc_Data[2] = {inv_bits(inv_crc16_H[1]), inv_bits(inv_crc16_H[0])};
 _tprintf(_T("根据CRC计算出的数据: 0x%02X 0x%02X\n"), inv_crc_Data[0], inv_crc_Data[1]);
 
 return 0;
}

// 将一个字节的bits逆序
// http://blog.csdn.net/jakee304/article/details/2152655
unsigned char inv_bits(unsigned char c)
{
 // 原始位序: 7 6 5 4 3 2 1 0

 // 位序变为: 6 7 4 5 2 3 0 1
 c = (c & 0xaa) >> 1 | (c & 0x55) << 1;
 
 // 位序变为: 4 5 6 7 0 1 2 3
 c = (c & 0xcc) >> 2 | (c & 0x33) << 2;
 
 // 位序变为: 0 1 2 3 4 5 6 7
 c = (c & 0xf0) >> 4 | (c & 0x0f) << 4;

 return c;
}

 

// CRC.h

#pragma once

class CRC16_H
{
public:
 CRC16_H(unsigned short polynomial)
 {
  // polynomial 多项式系数, 如CCITT-CRC16: x16+x12+x5+1, 则为0x1021
  for(int i=0; i<256; ++i)
  {
   crc16_tableH[i] = do_crcH(polynomial, (unsigned char)i);
  }
 }
 unsigned short do_crcH(unsigned short crcInit, unsigned char *message, unsigned int len)
 {
  unsigned short int crc = crcInit;
  while(len--)
  {
   crc = (crc<<8) ^ crc16_tableH[((crc>>8) ^ *message++) & 0xff];
  }
  return crc;
 }

private:
 unsigned short do_crcH(unsigned short polynomial, unsigned char message)
 {
  unsigned crc = 0;
  unsigned short bitTable[2] = {0, polynomial};
  for(int i=7; i>=0; --i)
  {
   crc = (crc<<1) ^ bitTable[((crc>>15) ^ (message>>i)) & 0x01];
  }

  return crc;
 }
 unsigned short crc16_tableH[256];
};

 

抱歉!评论已关闭.