CRC16常見幾個標準的演算法及C語言實現__演算法

來源:互聯網
上載者:User

CRC16常見的標準有以下幾種,被用在各個規範中,其演算法原理基本一致,就是在資料的輸入和輸出有所差異,下邊把這些標準的差異列出,並給出C語言的演算法實現。

CRC16_CCITT:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在後,結果與0x0000異或

CRC16_CCITT_FALSE:多項式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在後,高位在前,結果與0x0000異或

CRC16_XMODEM:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在後,高位在前,結果與0x0000異或

CRC16_X25:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在後,結果與0xFFFF異或

CRC16_MODBUS:多項式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在後,結果與0x0000異或

CRC16_IBM:多項式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在後,結果與0x0000異或

CRC16_MAXIM:多項式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在後,結果與0xFFFF異或

CRC16_USB:多項式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在後,結果與0xFFFF異或

模式

多項式

初始值

資料位元序

結果處理

CRC16_CCITT

x16+x12+x5+1(0x1021)

0x0000

低位在前,高位在後

與0x0000異或

CRC16_CCITT_FALSE

x16+x12+x5+1(0x1021)

0xFFFF

低位在後,高位在前

與0x0000異或

CRC16_XMODEM

x16+x12+x5+1(0x1021)

0x0000

低位在後,高位在前

與0x0000異或

CRC16_X25

x16+x12+x5+1(0x1021)

0x0000

低位在後,高位在前

與0xFFFF異或

CRC16_ MODBUS

x16+x15+x2+1(0x8005)

0xFFFF

低位在前,高位在後

與0x0000異或

CRC16_ IBM

x16+x15+x2+1(0x8005)

0x0000

低位在前,高位在後

與0x0000異或

CRC16_ MAXIM

x16+x15+x2+1(0x8005)

0x0000

低位在前,高位在後

與0xFFFF異或

CRC16_ USB

x16+x15+x2+1(0x8005)

0xFFFF

低位在前,高位在後

與0xFFFF異或

多項式產生:
如x16+x12+x5+1
x16表示第16位為1,x5表示第5位為1
(1 << 16) | (1 << 12) | (1 << 5) | (1) = 0x11021
但是CRC16隻取低16位,寫成16進位數就是 0x1021

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){  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) ;}unsigned short CRC16_CCITT_FALSE(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0xFFFF;  unsigned short wCPoly = 0x1021;  unsigned char wChar = 0;    while (usDataLen--)   {        wChar = *(puchMsg++);        wCRCin ^= (wChar << 8);        for(int i = 0;i < 8;i++)        {          if(wCRCin & 0x8000)            wCRCin = (wCRCin << 1) ^ wCPoly;          else            wCRCin = wCRCin << 1;        }  }  return (wCRCin) ;}unsigned short CRC16_XMODEM(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0x0000;  unsigned short wCPoly = 0x1021;  unsigned char wChar = 0;    while (usDataLen--)   {        wChar = *(puchMsg++);        wCRCin ^= (wChar << 8);        for(int i = 0;i < 8;i++)        {          if(wCRCin & 0x8000)            wCRCin = (wCRCin << 1) ^ wCPoly;          else            wCRCin = wCRCin << 1;        }  }  return (wCRCin) ;}unsigned short CRC16_X25(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0xFFFF;  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^0xFFFF) ;}unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0xFFFF;  unsigned short wCPoly = 0x8005;  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) ;}unsigned short CRC16_IBM(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0x0000;  unsigned short wCPoly = 0x8005;  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) ;}unsigned short CRC16_MAXIM(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0x0000;  unsigned short wCPoly = 0x8005;  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^0xFFFF) ;}unsigned short CRC16_USB(unsigned char *puchMsg, unsigned int usDataLen){  unsigned short wCRCin = 0xFFFF;  unsigned short wCPoly = 0x8005;  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^0xFFFF) ;}
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];}void InvertUint32(unsigned int *dBuf,unsigned int *srcBuf){    int i;    unsigned int tmp[4];    tmp[0] = 0;        for(i=0;i< 32;i++)    {      if(srcBuf[0]& (1 << i))        tmp[0]|=1<<(15 - i);    }    dBuf[0] = tmp[0];}

具體驗證請使用這個工具,內含CRC所有演算法的計算

在這個基礎上也加入CRC32 的校正演算法

//CRC32演算法:unsigned int CRC32(unsigned char *puchMsg, unsigned int usDataLen){  int i;  unsigned int wCRCin = 0xFFFFFFFF;  unsigned int wCPoly = 0x04C11DB7;  unsigned int wChar = 0;  while (usDataLen--)   {        wChar = *(puchMsg++);        InvertUint8((unsigned char *)&wChar,(unsigned char *)&wChar);        wCRCin ^= (wChar << 24);        for(i = 0;i < 8;i++)        {          if(wCRCin & 0x80000000)            wCRCin = (wCRCin << 1) ^ wCPoly;          else            wCRCin = wCRCin << 1;        }  }  InvertUint32(&wCRCin,&wCRCin);  return (wCRCin ^ 0xFFFFFFFF) ;}
對於CRC32可能還有其他的多項式和初始值和結果值是否需要異或以及輸入資料是否需要位序倒轉等要求在源碼中修改


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.