加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

CRC8,CRC16常见几个标准的算法及C语言实现

发布时间:2020-12-15 04:51:17 所属栏目:百科 来源:网络整理
导读:参考网址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 c

参考网址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

? {


? ? 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];


}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读