From principle to implementation of CRC

Source: Internet
Author: User
Tags crc32

Abstract: CRC (cyclic redundancy check) is widely used in error detection during data communication.
Error Checking capability. This article describes in detail the basic principles of CRC and explains the concept of the common lookup algorithm.
Implementation methods.

1. Error Detection
----------
In data communication, the receiving end needs to check whether errors occur during transmission. common technologies include parity (parity ).
Check), checksum, and CRC (cyclic redundancy check ). They are all sent to the message according
An algorithm calculates the verification code and sends the verification code and message together to the receiving end. The receiving end is connected to the received message
The same algorithm is used to obtain the verification code and compare it with the Received verification code to determine whether the received message is correct.

The parity check only requires one-bit verification code, and its calculation method is also very simple. Taking the odd test as an example, the sender only needs
Bitwise XOR operation. If the obtained value is 0, the verification code is 1; otherwise, it is 0. The acceptor can calculate messages in the same way.
And then compare the verification code. You can also calculate the message together with the verification code. If the value is 0, an error occurs. Otherwise, the verification is successful.
In general, the parity check can detect a one-bit error. In fact, it can detect any odd digit error.

The concept of checksum is also very simple. It regards the transmitted message as a sequence of 8-bit (or 16/32-bit) integers and adds these Integers
The verification code is also called the verification code. The Checksum is used in the IP protocol and is calculated based on a 16-bit integer.
The carry of MSB (most significant bit) is added to the result.

Obviously, both parity and checksum are obviously insufficient. An even number of errors cannot be detected during the parity check. For checksum,
If there are two integer errors in the integer sequence, one adds a certain value, and the other decreases the same value, this error
It cannot be detected.

2. Basic principles of the CRC algorithm
-------------------
The CRC algorithm is based on the polynomial arithmetic of GF (2) (2 element galova domain). It sounds terrible, but in fact it
The main features and operational rules of the service are well understood.

There is only one variable X in the GF (2) polynomial, and its coefficients are only 0 and 1, for example:
1 * x ^ 7 + 0 * x ^ 6 + 1 * x ^ 5 + 0 * x ^ 4 + 0 * x ^ 3 + 1 * x ^ 2 + 1 * x ^ 1 + 1 * x ^ 0
That is:
X ^ 7 + x ^ 5 + x ^ 2 + x + 1
(X ^ n indicates the N power of X)

In GF (2) polynomials, the addition and subtraction of the coefficients on the corresponding item are performed using the modulo 2 arithmetic. The modulo 2 is the addition and subtraction without considering carry and borrow places,
That is:
0 + 0 = 0 0-0 = 0
0 + 1 = 1 0-1 = 1
1 + 0 = 1 1-0 = 1
1 + 1 = 0 1-1 = 0

Obviously, addition and subtraction have the same effect (therefore, "-" is generally not displayed in GF (2) polynomials), which is equivalent to exclusive or operation. Example
For example, P1 = x ^ 3 + x ^ 2 + 1, P2 = x ^ 3 + x ^ 1 + 1, P1 + P2 is:

X ^ 3 + x ^ 2 + 1
+ X ^ 3 + x + 1
------------------
X ^ 2 + x

GF (2) polynomial multiplication is basically the same as general polynomial multiplication, but is performed by modulo 2 when each item is added. For example
P1 * P2:

(X ^ 3 + x ^ 2 + 1) (x ^ 3 + x ^ 1 + 1)
= (X ^ 6 + x ^ 4 + x ^ 3
+ X ^ 5 + x ^ 3 + x ^ 2
+ X ^ 3 + x + 1)
= X ^ 6 + x ^ 5 + x ^ 4 + x ^ 3 + x ^ 2 + x + 1

GF (2) polynomial division is basically the same as general polynomial division, but it is only performed by modulo 2 during subtraction. For example:
For example, P3 = x ^ 7 + x ^ 6 + x ^ 5 + x ^ 2 + X, P3/P2 is:

X ^ 4 + x ^ 3 + 1
------------------------------------------
X ^ 3 + x + 1) x ^ 7 + x ^ 6 + x ^ 5 + x ^ 2 + x
X ^ 7 + x ^ 5 + x ^ 4
---------------------
X ^ 6 + x ^ 4
X ^ 6 + x ^ 4 + x ^ 3
---------------------
X ^ 3 + x ^ 2 + x
X ^ 3 + x + 1
-----------------
X ^ 2 + 1

The CRC algorithm maps a message with m-bit length to a GF (2) polynomial M. For example, if an 8-bit message is 11100110
MSB, the polynomial corresponding to it is x ^ 7 + x ^ 6 + x ^ 5 + x ^ 2 + X. The sender and acceptor agree that the number of times is R
GF (2) polynomial g, called the generative polynomial, for example, x ^ 3 + x + 1, R = 3. Add multiple numbers corresponding to R 0 to the message.
The entry is m', and obviously M' = Mx ^ r. Divide m' by G to obtain the remainder polynomial R with a number equal to or less than R-1,
The corresponding R-bit value is the verification code. As follows:

11001100
-------------
1011) 11100110000
1011 .......
----.......
1010 ......
1011 ......
----......
1110...
1011...
----...
1010 ..
1011 ..
----
100 <--- Verification Code

The sender sends the M-bit message together with the R-bit verification code (m' + r), and the receiver calculates and receives the message in the same way.
The Mbit message verification code, and then compare it with the Received verification code. The acceptor can also divide all received M + R BITs by the raw
To determine whether the remainder is 0. This is because, M' + r = (QG + r) + R = QG, where Q is the vendor. Display
However, it can also add r 0 after all M + R, just like the sender, and then divide it by the generated polynomial. If there is no error
The remainder is still 0.

3. Selection of generating Polynomials
------------------
Obviously, the error checking capability varies depending on the generated polynomials. How to select a good generative polynomial requires
Here, we will only make some analysis from some aspects. Obviously, to use the r bit verification code, the number of times the polynomial is generated should be
R. The generated polynomial should contain the entry "1", otherwise the LSB (least significant bit) of the Verification Code will always be 0. If
If the message (including the verification code) T produces an error during transmission, the message received by the receiving end can be expressed as t + E. If e is not
This error can be detected if the generated polynomial G is exhausted. Consider the following situations:

1) 1-bit error, that is, E = x ^ n = 100... 00, N> = 0. As long as G has at least 2 bits and 1 bits, e cannot be wiped out by G. This
It is because GX ^ K is equivalent to moving G to the left K bit. For any polynomial Q, QG is equivalent to moving multiple different G to the left.
If G has at least two values of 1, multiple different left-shift addition results of at least two values of 1.

2) odd digit error. e cannot be wiped out by G as long as G contains factor F = x + 1. This is because QG = q'f, from 1)
The number of digits of result 1 must be an even number.

3) Explosive errors, that is, E = (x ^ N +... + 1) x ^ m = 1... 100... 00, N> = 1, m> = 0, apparently only
If you want g to include item "1" and the number of times is greater than N, you cannot remove E.

4) two-digit error, that is, E = (x ^ n + 1) x ^ m = 100... 00100... 00, N> = 0. Set x ^ n + 1 = QG + R,
Then E = qgx ^ m + RX ^ m, from 3) We can see that e can be wiped out by G and only when R is 0. Therefore, you only need to analyze the x ^ n + 1, Root
According to [3], for the number of times R, there is always a generated polynomial g, so that the minimum N is 2 ^ r-1, in addition to x ^ n
+ 1. This generated polynomial is called the original (primitive), which provides the maximum number of errors detected by two digits.
Capability, because when n = 2 ^ r-1, x ^ n + 1 can be wiped out by any r subpolynomials. [3] also states that the original
The generated polynomials are not allowed to be divided, but not necessarily the original polynomials. Therefore, for some
Odd digit error. The original generated polynomials cannot be detected.
 
The following are the polynomials generated by some standard CRC algorithms:
 
Standard polynomial hexadecimal Representation
---------------------------------------------------------------------------
Crc12 x ^ 12 + x ^ 11 + x ^ 3 + x ^ 2 + x + 1 80f
Crc16 x ^ 16 + x ^ 15 + x ^ 2 + 1 8005
CRC16-CCITT x ^ 16 + x ^ 12 + x ^ 5 + 1 1021
CRC32 x ^ 32 + x ^ 26 + x ^ 23 + x ^ 22 + x ^ 16 + x ^ 12 + x ^ 11 04c11db7
+ X ^ 10 + x ^ 8 + x ^ 7 + x ^ 5 + x ^ 4 + x ^ 2 + x + 1

In hexadecimal notation, the maximum number of items is removed, and CCITT was renamed as ITU-T in 1993. Crc12 is used for 6-bit bytes, and others are used for 8-bit
Bytes. Crc16 in IBM's bisynch communication standard. CRC16-CCITT is widely used in XMODEM, X.25 and SDLC communication.
Protocol. While Ethernet and FDDI use CRC32, which is also used in zip, rar, and Other File compression. In these generated Polynomials
CRC32 is original, and the other three contain factor x + 1.

4. Implementation of the CRC algorithm
---------------
To use a program to implement the CRC algorithm, consider the transformation of the long division in section 2nd, still M = 11100110, G = 1011,
The coefficient R is 3.

11001100 11100110000
------------- 1011
1011) 11100110000 -----------
1011 ...... 1010110000
---- ...... 1010110000
1010 ...... 1011
1011 ...... ==> -----------
---- ...... 001110000
1110... 1110000
1011... 1011
----...-----------
1010 .. 101000
1011 .. 101000
---- 1011
100 <--- Verification Code -----------
00100
100 <--- Verification Code

The program can be implemented as follows:
1) put the first R bit of MX ^ r into a register with a length of R;
2) If the first part of the register is 1, move the Register to the left by 1 (move MSB of MX ^ r to the LSB of the register ),
It is the same or as the back r bit of G. Otherwise, it only shifts the register one bit left (move the MSB of MX ^ r to the LSB of the Register );
3) Repeat Step 1 until all MX ^ r m is moved into the register;
4) the value in the Register is the verification code.

Using the CRC16-CCITT to generate a polynomial 0X1021, its C code (all the code in this paper assumes that the system is 32 bits, and all are in the vc6
Compiled as follows:

Unsigned short do_crc (unsigned char * message, unsigned int Len)
{
Int I, J;
Unsigned short crc_reg;

Crc_reg = (Message [0] <8) + message [1];
For (I = 0; I <Len; I ++)
{
If (I <len-2)
For (j = 0; j <= 7; j ++)
{
If (short) crc_reg <0)
Crc_reg = (crc_reg <1) + (Message [I + 2]> (7-I) ^ 0X1021;
Else
Crc_reg = (crc_reg <1) + (Message [I + 2]> (7-I ));
}
Else
For (j = 0; j <= 7; j ++)
{
If (short) crc_reg <0)
Crc_reg = (crc_reg <1) ^ 0X1021;
Else
Crc_reg <= 1;
}
}
Return crc_reg;
}

Obviously, the behavior of each inner loop depends on the first place in the register. Because the exclusive or operation satisfies the exchange rate and combination law, and is different from 0
Or, the message can not be moved into the register. In each internal loop, the first part of the register is followed by the corresponding message bit.
Exclusive or. The improved code is as follows:

Unsigned short do_crc (unsigned char * message, unsigned int Len)
{
Int I, J;
Unsigned short crc_reg = 0;
Unsigned short current;

For (I = 0; I <Len; I ++)
{
Current = message [I] <8;
For (j = 0; j <8; j ++)
{
If (short) (crc_reg ^ current) <0)
Crc_reg = (crc_reg <1) ^ 0X1021;
Else
Crc_reg <= 1;
Current <= 1;
}
}
Return crc_reg;
}

In the above discussion, each byte of the message is first transmitted MSB, The CRC16-CCITT standard is according to the first transmission LSB, the message
Right Shift to register for calculation. You only need to change the code to the LSB used to determine the Register, and convert 0x1021 to 0x8408 and
The registers can be exclusive or, as shown below:

Unsigned short do_crc (unsigned char * message, unsigned int Len)
{
Int I, J;
Unsigned short crc_reg = 0;
Unsigned short current;

For (I = 0; I <Len; I ++)
{
Current = message [I];
For (j = 0; j <8; j ++)
{
If (crc_reg ^ current) & 0x0001)
Crc_reg = (crc_reg> 1) ^ 0x8408;
Else
Crc_reg> = 1;
Current >>= 1;
}
}
Return crc_reg;
}

This algorithm uses a two-tier loop to process messages in bit by bit, which is very inefficient. To improve time efficiency
The common idea is to change the space for time. Considering that the inner loop is only related to the current message byte and the low byte of crc_reg
The algorithm performs the following equivalent conversions:

Unsigned short do_crc (unsigned char * message, unsigned int Len)
{
Int I, J;
Unsigned short crc_reg = 0;
Unsigned char index;
Unsigned short to_xor;

For (I = 0; I <Len; I ++)
{
Index = (crc_reg ^ message [I]) & 0xff;
To_xor = index;
For (j = 0; j <8; j ++)
{
If (to_xor <0x0001)
To_xor = (to_xor> 1) ^ 0x8408;
Else
To_xor> = 1;
}
Crc_reg = (crc_reg> 8) ^ to_xor;
}
Return crc_reg;
}

Now the inner loop is only related to the index. You can generate a crc16_ccitt_table table in the form of an array in advance, so that
To_xor = crc16_ccitt_table [Index], which can be simplified:

Unsigned short do_crc (unsigned char * message, unsigned int Len)
{
Unsigned short crc_reg = 0;

While (Len --)
Crc_reg = (crc_reg> 8) ^ crc16_ccitt_table [(crc_reg ^ * message ++) & 0xff];

Return crc_reg;
}

Crc16_ccitt_table is generated using the following code:

Int main ()
{
Unsigned char Index = 0;
Unsigned short to_xor;
Int I;

Printf ("unsigned short crc16_ccitt_table [256] = \ n {");
While (1)
{
If (! (Index % 8 ))
Printf ("\ n ");

To_xor = index;
For (I = 0; I <8; I ++)
{
If (to_xor <0x0001)
To_xor = (to_xor> 1) ^ 0x8408;
Else
To_xor> = 1;
}
Printf ("0x % 04x", to_xor );

If (Index = 255)
{
Printf ("\ n ");
Break;
}
Else
{
Printf (",");
Index ++;
}
}
Printf ("};");
Return 0;
}

The generated table is as follows:

Unsigned short crc16_ccitt_table [1, 256] =
{
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0 xbfdb, 0xae52, 0 xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0 xbdcb, 0xac42, 0x9ed9, 0x8f50, 0 xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x0000c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0 xdecd, 0xcf44, 0 xfddf, 0xec56, 0x98e9, 0x8960, 0 xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0 xffcf, 0xee46, 0 xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x060, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa133,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};

In this case, for the message unsigned char message [Len], the verification code is:
Unsigned short code = do_crc (message, Len );
And send it as follows:
Message [Len] = Code & 0x00ff;
Message [Len + 1] = (code> 8) & 0x00ff;

The receiving end executes do_crc for the received Len + 2 bytes. If no error occurs, the result should be 0.

In some transmission protocols, the sender does not specify the message length, but uses the end mark. The following errors are considered:
1) add one or more 0 bytes before the message;
2) The message starts with one or more consecutive 0 bytes and loses one or more 0;
3) after the message (including the verification code), add one or more 0 bytes;
4) The message (including the verification code) ends with one or more consecutive 0 bytes and loses one or more 0;

Obviously, none of these errors can be detected because if the register value is 0, 0 message bytes (or bits) are processed and sent
The memory value remains unchanged. To solve the first two problems, we only need to make the initial value of the Register not 0, and make the following improvements to do_crc:
 
Unsigned short do_crc (unsigned short reg_init, unsigned char * message, unsigned int Len)
{
Unsigned short crc_reg = reg_init;

While (Len --)
Crc_reg = (crc_reg> 8) ^ crc16_ccitt_table [(crc_reg ^ * message ++) & 0xff];

Return crc_reg;
}

In the CRC16-CCITT standard reg_init = 0 xFFFF,
The calculated verification code is different from 0xffff, that is:
Unsigned short code = do_crc (0 xFFFF, message, Len );
Code ^ = 0 xFFFF;
Message [Len] = Code & 0x00ff;
Message [Len + 1] = (code> 8) & 0x00ff;

Obviously, the receiving end executes do_crc on all received bytes. If no error occurs, the result should be a constant value.
Good_crc. It meets the following requirements:
Unsigned char P [] = {0xff, 0xff };
Good_crc = do_crc (0, P, 2 );
The result is good_crc = 0xf0b8.

References
--------
[1] Ross N. Williams, "a painless guide to CRC error detection algorithms", version 3,
Http://www.ross.net/crc/crcpaper.html,August 1993
[2] Simpson, W., editor, "PPP in HDLC framing", RFC 1549, December 1993
[3] P. E. Boudreau, W. C. Bergman and D. R. lrvin, "Performance of a Cyclic Redundancy
Check and its interaction with a data scrambler ", ibm j. res. Develop., vol.38
No. 6, November 1994

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.