A method to implement CRC checksum using C language _c language

Source: Internet
Author: User

CRC (Cyclic redundancy check) calibration application is more extensive, previously in order to deal with the simple, most of the program using LRC (longitudinal redundancy check) checksum, LRC check very well understood that the programming is simple. Spent a day studying CRC's C language implementation, understanding and mastering the Basic principles and C language programming. Simply write it down with your own understanding.

1, CRC Introduction

The basic idea of CRC test is to use linear coding theory, in the sending end according to the K-bit binary code sequence to be transmitted, a certain rule produces a check code R bit (CRC code), attached to the information behind, constitute a new binary sequence number of total (k+r) bit, and finally sent out. The receiving end is validated against the same rules to determine if there is an error in the transfer. The receiver has two kinds of processing methods: 1, the K-bit sequence of CRC code, compared with the received CRC, consistent receive the correct. 2, calculate the whole k+r bit CRC code, if 0, then receive the correct.
CRC code has a number of test digits, 8-bit, 16-bit, 32-bit, and so on, the same principle. The 16-bit CRC code produces the rule is to send the binary sequence number left 16 bits (that is, multiplied by 2 of 16 times), divided by a polynomial, the final remainder is the CRC code.
CRC code for the use of the Model 2 algorithm, that is, the polynomial division with no borrow subtraction operation, the operation is equivalent to XOR or operation. This should be carefully understood, is the basis of programming.
CRC-16: (used in the US binary synchronous system) G (X) = X16 + X15 + X2 + 1
Crc-ccitt: (recommended by European CCITT) G (X) = X16 + X12 + X5 + 1
Crc-32:g (X) = X32 + X26 + X23 + X22 + X16 +x12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + 1

2. Calculate CRC by Bit

Adopt Crc-ccitt polynomial, polynomial for 0x11021,c language programming, participate in calculation for 0x1021, this place must think deeply to realize the mystery, share my thought: When the CRC is computed by bit, for example, the binary sequence is 1001 1010 1010 When 1111, the binary sequence number is shifted left 16 digits, that is 1001 1010 1010 1111 (0000 0000 0000 0000), the binary sequence can be split into 1000 0000 0000 0000 (0000 0000 0000 0000) + 00 0 0000 0000 0000 (0000 0000, 0000 0000) + 00 0000 0000 (0000 0000 0000 0000) + 0000 1 0000 0000 (0000 0000, 0000 0000) + ...
To begin the analysis operation now:
<1> to find the remainder of the first binary sequence, vertical division is 0x10000 ^ 0x11021 operation, followed by 0-bit retention;
<2> then the second binary sequence to the remainder, the first operation of the remainder *2 and the second binary sequence to 0x11021, this step understanding should be no problem. If the sequence is 0, no calculation is required.
<3> the remainder of the binary sequence is the same as the previous two steps.
<4> the last one is the remainder of the whole binary sequence, which is the CRC parity code.
The calculation method is equivalent to each bit of computation, the operation process is easy to understand, the memory is less, the disadvantage is a calculation more time-consuming.
The C language implementation method is given below:

Copy Code code as follows:

unsigned char test[16] = {0X00,0X11,0X22,0X33,0X44,0X55,0X66,0X77,0X88,0X99,0XAA,0XBB,0XCC,0XDD,0XEE,0XFF};
unsigned char len = 16;
void Main (void)
{
unsigned long temp = 0;
unsigned int CRC;
unsigned char i;
unsigned char *ptr = test;

while (len--) {
for (i = 0x80 i!= 0; i = i >> 1) {
temp = temp * 2;
if (temp & 0x10000)!= 0)
temp = temp ^ 0x11021;

if ((*ptr & i)!= 0)
temp = temp ^ (0x10000 ^ 0x11021);

}
ptr++;
}
CRC = temp;
printf ("0x%x", CRC);
}


The above procedure is based on operational analysis and is easy to understand. In order to conserve memory space, we make further simplification of the program. The analysis shows that when the last calculated remainder in the binary sequence is 15bit, that is, (the last calculated remainder & 0x8000)!= 0, the 0x11021 can be evaluated after the first residual * 2, and then the remainder is added to the standard calculation. This is well understood, that is to say, for example, think of it as a simple division, calculate the last one when the remainder multiplied by 2, if the larger can be a divisor, then remove the divisor. One thing is different from ordinary division, because the borrow subtraction is used in polynomial division, so 0x10000 can be 0x11021 apart, the remainder is not 0x10000, but 0x1021. I'll know it by myself. The sum of the remainder is also an addition operation with no carry, that is, XOR. Finally, it is emphasized that since the binary sequence is involved in the operation after 16-bit left shift, it is important to understand that the last one to be counted to the sequence is also to be removed. The following is a simplified C language implementation.
Copy Code code as follows:

unsigned char test[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
void Main (void)
{
unsigned int CRC = 0;
unsigned char i;
unsigned char *ptr = test;

while (len--) {
for (i = 0x80 i!= 0; i = i >> 1) {
if (CRC & 0x8000)!= 0) {
CRC = CRC << 1;
CRC = CRC ^ 0x1021;
}
else {
CRC = CRC << 1;
}
if ((*ptr & i)!= 0) {
CRC = CRC ^ 0x1021;
}
}
ptr++;
}

printf ("0x%x", CRC);
}


The above procedure is more common online, but there is no detailed explanation. Through the detailed analysis above, if there are difficulties in understanding the procedure, you can compare the previous procedure without simplifying, savor a ha, or it is easier to understand. If you can not understand, or look at the beginning, I code so many words easy ...
In-place CRC code is relatively simple, accounting for less memory, but to a one to calculate, the following introduces a byte look-up table quickly calculate CRC method.

3. Calculate CRC by Byte

With the knowledge of the above bitwise calculation, understanding this is a small case. Or the previous example: When the byte computes the CRC, for example, when calculating a binary sequence of 1001 1010 1010 1111, that is, when 0x9a9f, the binary sequence number is shifted to the left 16 bit, that is 0x9a9f (0 0 0 0), in fact the binary sequence can be split into 0x9a00 (0 0 0 0) + 0x009f (0 0 0 0), the analysis of calculations and the above steps, the only difference is that the last step in the calculation of the remainder CRC multiplied by 2 of eight to participate in the next operation, this should be good understanding of Satan. In order to simplify programming, the CRC in the calculation is split into a high eight-bit and a low eight-bit form, and a high eight-bit value is directly added to the standard value, and the lower eight-bit value is multiplied by 2-squared, which is added as the remainder and the calculated remainder. In order to improve the speed of calculation, we calculate the CRC of the 8-bit binary sequence number and put it in a table, so the calculation speed can be greatly improved by look-up table method.
How did the table get it? Of course is calculated, the following program gives a polynomial is a 0x11021 calculation program.

Copy Code code as follows:

void Main (void)
{
unsigned int CRC = 0;
unsigned char i;
unsigned int J;

for (j = 0; J < 256; J + +) {
CRC = 0;
for (i = 0x80 i!= 0; i = i >> 1) {
if (CRC & 0x8000)!= 0) {
CRC = CRC << 1;
CRC = CRC ^ 0x1021;
}
else {
CRC = CRC << 1;
}
if (J & i)!= 0) {
CRC = CRC ^ 0x1021;
}
}
printf ("0x");
if (CRC < 0x10) {
printf ("000");
}
else if (CRC < 0x100) {
printf ("00");
}
else if (CRC < 0x1000) {
printf ("0");
}

printf ("%x,", CRC);
}
}


If you are not using the 0x11021 polynomial, simply change the 0x1021 in the program to something else. After a few printf statements to control the resulting table is more neat, if it doesn't matter, you can directly use printf ("0x%x,", CRC); The resulting table is as follows:
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0XD1AD, 0xe1ce, 0x F1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0X62D6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0XD3BD, 0xc39c, 0xf3 FF, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0X44A4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0XF5CF , 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0XF7DF, 0xe7fe, 0xd79d, 0XC7BC, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0XF9AF, 0x 8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0XDBFD, 0XCBDC, 0XFBBF, 0xeb 9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0X3C03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec , 0XDDCD, 0XAD2A, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0XDFDD, 0XCFFC, 0XBF1B,0XAF3A, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0X30C2, 0x20e3, 0x 5004, 0x4025, 0x7046, 0x6067, 0X83B9, 0x9398, 0XA3FB, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0X22F3, 0x32 D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0XA5CB, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0X24C3, 0x14a0 , 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0X36F2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x 4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0XABBB, 0xbb9a, 0x4a 0x5a54, 0x6a37, 0x7a16, 0X0AF1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0XCD4D, 0xbdaa, 0xad8b, 0x9de8, 0X8DC9 , 0x7c26, 0x6c07, 0X5C64, 0x4c45, 0X3CA2, 0x2c83, 0x1ce0, 0X0CC1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0XBFBA, 0X8FD9, 0x9ff8, 0x6e17, 0x7e36,0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0X1EF0,
Okay, let's write the source program by byte:
Copy Code code as follows:

unsigned char test[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
unsigned int crc_table[256] ={
x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0XD1AD, 0xe1ce, 0xf 1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0X62D6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0XD3BD, 0xc39c, 0xf3f F, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0X44A4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0XF5CF, 0XC5AC, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0XF7DF, 0 Xe7fe, 0xd79d, 0XC7BC, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0XF9AF, 0x8 948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0XDBFD, 0XCBDC, 0XFBBF, 0xeb9 E, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0X3C03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0XDDCD, 0XAD2A, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0XEFBE, 0 XDFDD, 0XCFFC, 0XBF1B, 0XAF3A, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0X30C2, 0x20e3, 0x5 004, 0x4025, 0x7046, 0x6067, 0X83B9, 0x9398, 0XA3FB, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0X22F3, 0x32d 2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0XA5CB, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0X24C3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0X36F2, 0 x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4 865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0XABBB, 0xbb9a, 0x4a7 5, 0x5a54, 0x6a37, 0x7a16, 0X0AF1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0XCD4D, 0xbdaa, 0xad8b, 0x9de8, 0X8DC9, 0x7c26, 0x6c07, 0X5C64, 0x4c45, 0X3CA2, 0x2c83, 0x1ce0, 0X0CC1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0XBFBA, 0x8fd9, 0 X9ff8, 0x6e17, 0x7e36, 0X4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0X1EF0};
void Main (void)
{
unsigned int CRC = 0;
unsigned char crc_h8;
unsigned char *ptr = test;

while (len--) {
Crc_h8 = (unsigned char) (CRC >> 8);
CRC = CRC << 8;
CRC = CRC ^ crc_table[Crc_h8 ^ *ptr];
ptr++;
}
printf ("0x%x", CRC);
}


4. Calculate CRC by half byte

is not feeling the above table is too big, not very cool, we again to improve, by half byte calculation, principle I will not repeat, the procedure is as follows:

Copy Code code as follows:

unsigned char test[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
unsigned int crc_table[16] =
{0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0XD1AD, 0xe1ce, 0 Xf1ef
};
void Main (void)
{
unsigned int CRC = 0;
unsigned char crc_h4;
unsigned char *ptr = test;

while (len--)
{
Crc_h4 = (unsigned char) (CRC >> 12);
CRC = CRC << 4;
CRC = CRC ^ crc_table[Crc_h4 ^ (*ptr >> 4)];
Crc_h4 = (unsigned char) (CRC >> 12);
CRC = CRC << 4;
CRC = CRC ^ crc_table[Crc_h4 ^ (*ptr & 0x0f)];
ptr++;
}
printf ("0x%x", CRC);
}

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.