欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

CRC8 和 CRC16 算法以及几种通用标准的 C 语言实现

最编程 2024-04-13 15:42:29
...

参考网址CRC16常见几个标准的算法及C语言实现

先说一下CRC8的实现方式

CRC校验类型:CRC8/MAXIM

多项式:X8+X5+X4+1

Poly:0011 0001  0x31

高位放到后面就变成 1000 1100 0x8c

C现实代码:

unsigned char crc8_chk_value(unsigned char *message, unsigned char len)
{
    uint8 crc;
    uint8 i;
    crc = 0;
    while(len--)
    {
        crc ^= *message++;
        for(i = 0;i < 8;i++)
        {
            if(crc & 0x01)
            {
                crc = (crc >> 1) ^ 0x8c;
            }
                else crc >>= 1;
        }
    }
    return crc; 
}

这是映射颠倒的校验方式。

算法2
方法1:将存有数据的字节数组进行逐位计算,求得字节形式的CRC

typedef unsigned __int16    INT16U;
#define CRC_SEED   0xFFFF   // 该位称为预置值,使用人工算法(长除法)时 需要将除数多项式先与该与职位 异或 ,才能得到最后的除数多项式
#define POLY16 0x1021  // 该位为简式书写 实际为0x11021
INT16U crc16(unsigned char *buf,unsigned short length)
{
  INT16U shift,data,val;
  int i;

  shift = CRC_SEED;


  for(i=0;i<length;i++) 
  {
    if((i % 8) == 0)
      data = (*buf++)<<8;
    val = shift ^ data;
    shift = shift<<1;
    data = data <<1;
    if(val&0x8000)
      shift = shift ^ POLY16;
  }
  return shift;
}

算法3:
CRC16的算法原理:

1.根据CRC16的标准选择初值CRCIn的值。

2.将数据的第一个字节与CRCIn高8位异或。

3.判断最高位,若该位为 0 左移一位,若为 1 左移一位再与多项式Hex码异或。

4.重复3直至8位全部移位计算结束。

5.重复将所有输入数据操作完成以上步骤,所得16位数即16位CRC校验码。
根据算法原理与标准要求就能简单的写出具体程序:


unsigned short CRC16_CCITT(unsigned char *puchMsg, unsigned int usDataLen)---3个算法中,执行效率最快
{
  unsigned short wCRCin = 0x0000;
  unsigned short wCPoly = 0x1021;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        //InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  //InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin) ;
}


void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
{
    int i;
    unsigned char tmp[4];
    tmp[0] = 0;
    for(i=0;i< 8;i++)
    {
      if(srcBuf[0]& (1 << i))
        tmp[0]|=1<<(7-i);
    }
    dBuf[0] = tmp[0];
    
}


算法4
void CCRCDlg::CRCCCITT(const CHAR* pDataIn, int iLenIn, WORD* pCRCOut)  
{  
    WORD wTemp = 0;   
    WORD wCRC = 0xffff;   
  
    for(int i = 0; i < iLenIn; i++)   
    {          
        for(int j = 0; j < 8; j++)   
        {   
            wTemp = ((pDataIn[i] << j) & 0x80 ) ^ ((wCRC & 0x8000) >> 8);   
  
            wCRC <<= 1;   
  
            if(wTemp != 0)    
            {  
                wCRC ^= 0x1021;   
            }  
        }   
    }   
  
    *pCRCOut = wCRC;  

void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
{
    int i;
    unsigned char tmp[4];
    tmp[0] = 0;
    for(i=0;i< 8;i++)
    {
      if(srcBuf[0]& (1 << i))
        tmp[0]|=1<<(7-i);
    }
    dBuf[0] = tmp[0];
    
}
void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf)
{
    int i;
    unsigned short tmp[4];
    tmp[0] = 0;
    for(i=0;i< 16;i++)
    {
      if(srcBuf[0]& (1 << i))
        tmp[0]|=1<<(15 - i);
    }
    dBuf[0] = tmp[0];
}

推荐阅读