CRC 8,CRC 16よく見られるいくつかの標準的なアルゴリズムとC言語の実現
参考URL CRC 16よく見られるいくつかの標準的なアルゴリズムとC言語の実現
まずCRC 8の実現方法についてお話しします
これはマッピングが逆転した検証方式です.
アルゴリズム2方法1:データが格納されたバイト配列をビット単位で計算し、バイト形式のCRCを求める
typedef unsigned __int16 INT16U; #define CRC_SEED 0 xFFFF//このビットをプリセット値と呼び、人工アルゴリズム(長除法)を使用する場合、除数多項式を職位と異ならなければ、最後の除数多項式#define POLY 16 0 x 1021//このビットを簡略化して実際に0 x 1021 INT 16 U crc 16(unsigned char*buf,unsigned short length){INT 16 U 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:CRC 16のアルゴリズム原理:
1.初期値CRCInの値は、CRC 16の規格に従って選択される.
2.データの最初のバイトを、CRCInの高さ8ビットと異ならせる.
3.最上位を判断し、当該ビットが0であれば左シフトし、1であれば左シフトして多項式Hex符号と排他する.
4.8ビットの全てのシフト計算が終了するまで3を繰り返す.
5.すべての入力データ操作を繰り返して上記の手順を完了し、得られた16ビット数、すなわち16ビットCRC検査コード.アルゴリズムの原理と標準の要求によって簡単に具体的なプログラムを書くことができます:
unsigned short CRC16_CCITT(unsigned char*puchMsg,unsigned int usDataLen)---3つのアルゴリズムのうち、実行効率が最も速い{unsigned short wCRCin=0 x 0000;unsigned short wCPoly=0 x 1021;unsigned char wChar=0;while(usDataLen-){wChar=*(puchMsg+);//InvertUIT 8(&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< } dBuf[0] = tmp[0]; }
アルゴリズム4 void CCRCDlg::CRCCCITT(const CHAR*pDataIn,int iLenIn,WORD*pCRCOut){WORD wTemp=0;WORD wCRC=0 xffff;for(int i=0;i> 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< } 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< } dBuf[0] = tmp[0]; }
まずCRC 8の実現方法についてお話しします
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 0 xFFFF//このビットをプリセット値と呼び、人工アルゴリズム(長除法)を使用する場合、除数多項式を職位と異ならなければ、最後の除数多項式#define POLY 16 0 x 1021//このビットを簡略化して実際に0 x 1021 INT 16 U crc 16(unsigned char*buf,unsigned short length){INT 16 U 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:CRC 16のアルゴリズム原理:
1.初期値CRCInの値は、CRC 16の規格に従って選択される.
2.データの最初のバイトを、CRCInの高さ8ビットと異ならせる.
3.最上位を判断し、当該ビットが0であれば左シフトし、1であれば左シフトして多項式Hex符号と排他する.
4.8ビットの全てのシフト計算が終了するまで3を繰り返す.
5.すべての入力データ操作を繰り返して上記の手順を完了し、得られた16ビット数、すなわち16ビットCRC検査コード.アルゴリズムの原理と標準の要求によって簡単に具体的なプログラムを書くことができます:
unsigned short CRC16_CCITT(unsigned char*puchMsg,unsigned int usDataLen)---3つのアルゴリズムのうち、実行効率が最も速い{unsigned short wCRCin=0 x 0000;unsigned short wCPoly=0 x 1021;unsigned char wChar=0;while(usDataLen-){wChar=*(puchMsg+);//InvertUIT 8(&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< } dBuf[0] = tmp[0]; }
アルゴリズム4 void CCRCDlg::CRCCCITT(const CHAR*pDataIn,int iLenIn,WORD*pCRCOut){WORD wTemp=0;WORD wCRC=0 xffff;for(int i=0;i
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< } 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< } dBuf[0] = tmp[0]; }