# brief introduction

reference resources:
https://www.bilibili.com/video/BV1V4411Z7VA?from=search&seid=3373767585328853317&spm_ id_ From = 333.337.0.0 [reference 1]
This video is very clear and thorough. The first two sections of this article are mainly notes on the video content.

CRC cyclic redundancy check online calculation: http://www.ip33.com/crc.html [citation 2]

https://blog.csdn.net/C_Silence_K/article/details/105791642?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163323676916780261969661%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_ id=163323676916780261969661&biz_ id=0&utm_ medium=distribute.pc_ search_ result.none-task-blog-2allsobaiduend~default-2-105791642.first_ rank_ v2_ pc_ rank_ v29&utm_ Term = CRC% E5% 88% 9D% E5% A7% 8b% E5% 80% BC% E8% AF% A6% E7% BB% 86% E8% A7% A3% E9% 87% 8A & SPM = 1018.2226.3001.4187 [reference 3]
The third and fourth sections take the online CRC verification online calculation as an example for detailed analysis and implementation.

# 1. CRC manual calculus   # 2. Intuitive operation process of CRC # 3. Analysis of elements of online computing website interface  Init: This is the initialization preset value of the register (CRC) at the beginning of the algorithm, expressed in hexadecimal. The number of bits of Init is the same as that of polynomials, and its value is all 0 or all F. when all is 0, the subsequent calculation can be carried out after the CRC number of bits is added to the data (the data is obtained according to the value of RefIn) before the beginning of the algorithm. When all are 1, it means that before the algorithm starts, the first CRC digit (high bit) of the data is XOR with the corresponding digit 1 (i.e. the value of the first CRC digit is reversed by bit), and then the CRC digit 0 is added later for subsequent calculation.

If RefIn is False, it means that the 7th bit of each byte of the input raw data is the most significant bit, and the 0th bit is the least significant bit, that is, it can be calculated normally.
When RefIn is True, each byte of the input original data needs to be processed in reverse order. Note: it is for each byte, not the whole data. When Refout is False, the output is not processed. When Refout is True, the output data needs to be processed in reverse order of the whole data. Note: the reverse order here is different from RefIn. It is not in reverse order of bytes, but in reverse order of the whole data. Reference from [reference 3]

# crc_4 code implementation

```crc.h
#include <stdio.h>

#define DEBUG_CRC

uint8_t crc_4(uint32_t* pdata, uint32_t len);
uint8_t crc_8(uint32_t* pdata, uint32_t len);

enum CRC_NUM{
CRC_DATA_FORMAT_ERROR = 0,

CRC_SUCCESS
};
```
```crc.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "crc.h"

uint32_t crc_polynomical_4 = {0,0,1,1};
uint32_t crc_polynomical_8 = {0,0,0,0,0,1,1,1};

uint8_t crc_4(uint32_t* pdata, uint32_t len){
uint32_t i = 0,j = 0,k = 0,tmp = 0;
uint8_t crc = 0;
uint32_t crc_tmp = {0};

if((len-4) % 8 != 0) return CRC_DATA_FORMAT_ERROR;
#ifdef DEBUG_CRC
printf("original bit stream:");
for(i=0;i<len-4;i++){printf("%d ",pdata[i]);}
printf("\n");
#endif
for(i=0;i<(len-4)/8;i++){		/* reverse bit of input data in a byte */
for(j=0;j<4;j++){
tmp = pdata[i+j];
pdata[i+j] = pdata[i+7-j];
pdata[i+7-j] = tmp;
}
}
#ifdef DEBUG_CRC
printf("reverse bit stream:");
for(i=0;i<len-4;i++){printf("%d ",pdata[i]);}
printf("\n");
#endif
for (i=0;i<(len-4);i++)		/* crc calculate process */
{
if(pdata[i] == 1){
for(j=i+1,k=0;j<=i+4,k<4;j++,k++){
pdata[j] ^= crc_polynomical_4[k];
}
}
}
for(j=0;j<4;j++){		/* get result in byte */
crc_tmp[j] = pdata[i+j];
}
#ifdef DEBUG_CRC
printf("original result:");
for(j=0;j<4;j++){
printf("%d ",crc_tmp[j]);
if(j == 3) printf("\n");
}
#endif
for(i=0;i<2;i++){		/* reverse result,get final result */
tmp = crc_tmp[i];
crc_tmp[i] = crc_tmp[3-i];
crc_tmp[3-i] = tmp;
}
#ifdef DEBUG_CRC
printf("reverse result:");
for(j=0;j<4;j++){
printf("%d ",crc_tmp[j]);
if(j == 3) printf("\n");
}
#endif
return CRC_SUCCESS;
}

uint8_t crc_8(uint32_t* pdata, uint32_t len)
{

}
```
```main.c
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include "crc.h"

/* mainly function */
uint8_t crc_original_data_analysize(char* data,uint32_t len,uint8_t* recv_data,uint32_t recv_len,uint32_t* real_len);
uint8_t crc_bit_int(uint8_t* bit_data,uint32_t bit_len,uint32_t* int_data,uint32_t int_len);

/* tool function */
uint8_t char2value_hex(char c){
if(c >= '0' && c<= '9') return (c-'0');
else if(c >= 'a' && c <= 'f') return (c-'a'+10);
else if(c >= 'A' && c <= 'F') return (c-'A'+10);
else return -1;
}

int main(){
char crc_char = {0};
uint8_t crc_data = {0};
uint32_t real_len;
uint32_t crc_int[1024*8] = {0};
scanf("%s",crc_char);
crc_original_data_analysize(crc_char,strlen(crc_char),crc_data,1024,&real_len);
#ifdef DEBUG_CRC
printf("the data(dec,previous length:%ld (char),real length:%d (uint8_t):",strlen(crc_char),real_len);
for(uint32_t i=0;i<real_len;i++){
printf("%02d ",crc_data[i]);
}
printf("\n");
#endif
crc_bit_int(crc_data,real_len,crc_int,1024*8);
#ifdef DEBUG_CRC
printf("now every bit occupies a int:");
for(uint32_t i=0;i<real_len * 8;i++){
printf("%d ",crc_int[i]);
}
printf("\n");
#endif
/* '+4' mean that append four zero in the end,notice that real_len*8 must be smaller than 1024*8-4 */
crc_4(crc_int,real_len*8+4);
return 0;
}

uint8_t crc_original_data_analysize(char *data,uint32_t len,uint8_t* recv_data,uint32_t recv_len,uint32_t* real_len){
uint32_t cnt=0,recv_cnt = 0;
char data_tmp = {0};
uint8_t status = 0;
if(recv_len < len)
return 1;
while(cnt<len){
if(data[cnt] == ' '){
if(status == 0){cnt++;}
else {return 2;}
}
else{
if(status == 0){status = 1;data_tmp = data[cnt];cnt++;continue;}
if(status == 1){
status = 0;
data_tmp = data[cnt];
recv_data[recv_cnt] = char2value_hex(data_tmp)*16+char2value_hex(data_tmp);
cnt++;recv_cnt++;
}
}
}
*real_len = recv_cnt;
return 0;
}

uint8_t crc_bit_int(uint8_t* bit_data,uint32_t bit_len,uint32_t* int_data,uint32_t int_len){
if(int_len < bit_len*8) return 1;
for(uint32_t i=0;i<bit_len;i++){
for(uint32_t j=0;j<8;j++){
int_data[i*8+j] |= (bit_data[i] >> (7-j)) & 0x01;
}
}
return 0;
}
```

In the code, I changed the bit to uint32_t type is processed because it is 4 bytes long, which is easier for current processors to handle.
I wanted to write the CRC-32 code, but I was a little lazy..

Tags: C Linux

Posted on Sun, 03 Oct 2021 14:25:45 -0400 by tulleh