CRC16 common several standard algorithms and C language to achieve __ algorithm

Source: Internet
Author: User
Tags crc32 hex code

CRC16 common standards are used in various specifications, the principle of its algorithm is basically consistent, that is, in the data input and output differences, below the standards of the differences listed, and give the C language algorithm implementation.

Crc16_ccitt: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low in front, high in the post, results and 0x0000 different or

Crc16_ccitt_false: Polynomial x16+x12+x5+1 (0x1021), initial value 0xFFFF, low after, high in front, the result is different from 0x0000 or

Crc16_xmodem: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low after, high in front, result with 0x0000 xor or

crc16_x25: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low in front, high after, the result is different from 0xFFFF or

Crc16_modbus: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low in front, high in the rear, the result is different from 0x0000 or

CRC16_IBM: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low in front, high in the post, results and 0x0000 different or

Crc16_maxim: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low in front, high after, the result is different from 0xFFFF or

Crc16_usb: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low in front, high in the rear, the result is different from 0xFFFF or

Mode

Multi-item

Initial value

Data bit Order

Result processing

Crc16_ccitt

X16+x12+x5+1 (0x1021)

0x0000

Low in front, high in the back

Unlike 0x0000 or

Crc16_ccitt_false

X16+x12+x5+1 (0x1021)

0xFFFF

Low in the back, high in the front

Unlike 0x0000 or

Crc16_xmodem

X16+x12+x5+1 (0x1021)

0x0000

Low in the back, high in the front

Unlike 0x0000 or

crc16_x25

X16+x12+x5+1 (0x1021)

0x0000

Low in the back, high in the front

With 0xFFFF XOR or

Crc16_ MODBUS

X16+x15+x2+1 (0x8005)

0xFFFF

Low in front, high in the back

Unlike 0x0000 or

Crc16_ IBM

X16+x15+x2+1 (0x8005)

0x0000

Low in front, high in the back

Unlike 0x0000 or

Crc16_ MAXIM

X16+x15+x2+1 (0x8005)

0x0000

Low in front, high in the back

With 0xFFFF XOR or

Crc16_ USB

X16+x15+x2+1 (0x8005)

0xFFFF

Low in front, high in the back

With 0xFFFF XOR or

Multi-item Generation:
such as X16+x12+x5+1
x16 says the 16th bit is 1,x5 for the 5th digit is 1
(1 << 16) | (1 << 12) | (1 << 5) | (1) = 0x11021
But the CRC16 is only 16 digits low, written in the 16 number is 0x1021

CRC16 principle of the algorithm:

1. Select the value of the initial crcin according to the CRC16 criteria.

2. The first byte of the data is higher than the Crcin 8-bit.

3. Judge the highest bit, if the bit is 0 to move left one, if 1 left one again and polynomial hex code different or.

4. Repeat 3 until 8-digit total shift calculation ends. 5. Repeat all input data operations complete the above steps, the resulting 16 digits is 16-bit CRC check code.

According to the algorithm principle and standard requirements can be simple to write the specific procedures:

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 <&lT
          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,&amP;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]; &nb Sp
  Tmp[0] = 0;     for (i=0;i< 8;i++)     {      if (srcbuf[0]& (1 << i))     &N Bsp
  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))     & nbsp
  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];

 }

Specific validation please use this tool, which includes the calculation of all CRC algorithms

On this basis, we also add CRC32 verification algorithm.

CRC32 algorithm:
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 <<);
        for (i = 0;i < 8;i++)
        {
          if (wcrcin & 0x80000000)
            wcrcin = (wcrcin << 1) ^ wcpoly;
          else
            wcrcin = wcrcin << 1;
        }}
  InvertUint32 (&wcrcin,&wcrcin);
  Return (wcrcin ^ 0xFFFFFFFF);
}
For CRC32, there may be other polynomials and initial and result values that need to be different, or if the input data requires a bit-order reversal, etc., in the source code changes


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.