mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 08:46:42 +08:00
101 lines
6.8 KiB
Markdown
101 lines
6.8 KiB
Markdown
## Introduction
|
|
|
|
Data may encounter errors during the transmission process due to various reasons. To control errors in the transmission process, communication systems often adopt data verification to ensure the integrity of data.
|
|
Common data verification algorithms include sum check, parity check, exclusive OR check, Longitudinal Redundancy Check (LRC), and Cyclic Redundancy Check (CRC). The code for commonly used verification algorithms is also provided here.
|
|
|
|
## Interface
|
|
|
|
### General CRC
|
|
```c
|
|
// General CRC algorithm
|
|
uint32_t check_crc(uint8_t* data, uint32_t len, uint8_t width, uint32_t poly, uint32_t init, uint8_t refin, uint8_t refout, uint32_t xorout);
|
|
```
|
|
This CRC algorithm is a general CRC algorithm for data within 32 bytes. Besides passing in the data address and data length, it is followed by the width of the CRC check code, polynomial, initial value, input inversion, output inversion, and exclusive OR output in sequence.
|
|
This algorithm has the same usage method as [CRC (Cyclic Redundancy Check) Online Calculator](http://www.ip33.com/crc.html).
|
|
Randomly calculate a CRC using `check_crc` and compare it with the online tool.
|
|
```c
|
|
printf("crc 0x%X\r\n", check_crc("Hello", 5, 8, 0x5A, 0xAA, 1, 0, 0x4A));
|
|
```
|
|
The result is:
|
|
```
|
|
crc 0xE0
|
|
```
|
|
|
|
Based on commonly used CRC algorithms, they can be implemented through the `check_crc` macro definition.
|
|
```c
|
|
/*
|
|
|-------------------------------------------------------------------------------------------|
|
|
|CRC name | width | poly | init | xorout | refin | refout |
|
|
|-------------------------------------------------------------------------------------------|
|
|
|CRC-4/ITU | 4 | 03 | 00 | 00 | true | true |
|
|
|CRC-5/EPC | 5 | 9 | 09 | 00 | false | false |
|
|
|CRC-5/ITU | 5 | 5 | 00 | 00 | true | true |
|
|
|CRC-5/USB | 5 | 5 | 1F | 1F | true | true |
|
|
|CRC-6/ITU | 6 | 3 | 00 | 00 | true | true |
|
|
|CRC-7/MMC | 7 | 9 | 00 | 00 | false | false |
|
|
|CRC-8 | 8 | 7 | 00 | 00 | false | false |
|
|
|CRC-8/ITU | 8 | 7 | 00 | 55 | false | false |
|
|
|CRC-8/ROHC | 8 | 7 | FF | 00 | true | true |
|
|
|CRC-8/MAXIM | 8 | 1 | 00 | 00 | true | true |
|
|
|CRC-16/IBM | 16 | 005 | 0000 | 0000 | true | true |
|
|
|CRC-16/MAXIM | 16 | 005 | 0000 | FFFF | true | true |
|
|
|CRC-16/USB | 16 | 005 | FFFF | FFFF | true | true |
|
|
|CRC-16/MODBUS | 16 | 005 | FFFF | 0000 | true | true |
|
|
|CRC-16/CCITT | 16 | 021 | 0000 | 0000 | true | true |
|
|
|CRC-16/CCITT-FALSE | 16 | 021 | FFFF | 0000 | false | false |
|
|
|CRC-16/X25 | 16 | 021 | FFFF | FFFF | true | true |
|
|
|CRC-16/XMODEM | 16 | 021 | 0000 | 0000 | false | false |
|
|
|CRC-16/DNP | 16 | D65 | 0000 | FFFF | true | true |
|
|
|CRC-32 | 32 | 4C11DB7 | FFFFFFFF | FFFFFFFF | true | true |
|
|
|CRC-32/MPEG-2 | 32 | 4C11DB7 | FFFFFFFF | 00000000 | false | false |
|
|
|-------------------------------------------------------------------------------------------|
|
|
*/
|
|
#define check_crc4_itu(data, len) check_crc(data, len, 4, 0x03, 0x00, 1, 1, 0x00)
|
|
#define check_crc5_epc(data, len) check_crc(data, len, 5, 0x09, 0x09, 0, 0, 0x00)
|
|
#define check_crc5_usb(data, len) check_crc(data, len, 5, 0x05, 0x1F, 1, 1, 0x1F)
|
|
#define check_crc6_itu(data, len) check_crc(data, len, 6, 0x03, 0x00, 1, 1, 0x00)
|
|
#define check_crc7_mmc(data, len) check_crc(data, len, 7, 0x09, 0x00, 0, 0, 0x00)
|
|
#define check_crc8(data, len) check_crc(data, len, 8, 0x07, 0x00, 0, 0, 0x00)
|
|
#define check_crc8_itu(data, len) check_crc(data, len, 8, 0x07, 0x00, 0, 0, 0x55)
|
|
#define check_crc8_rohc(data, len) check_crc(data, len, 8, 0x07, 0xFF, 1, 1, 0x00)
|
|
#define check_crc8_maxim(data, len) check_crc(data, len, 8, 0x31, 0x00, 1, 1, 0x00)
|
|
#define check_crc16_ibm(data, len) check_crc(data, len, 16, 0x8005, 0x0000, 1, 1, 0x0000)
|
|
#define check_crc16_maxim(data, len) check_crc(data, len, 16, 0x8005, 0x0000, 1, 1, 0xFFFF)
|
|
#define check_crc16_usb(data, len) check_crc(data, len, 16, 0x8005, 0xFFFF, 1, 1, 0xFFFF)
|
|
#define check_crc16_modbus(data, len) check_crc(data, len, 16, 0x8005, 0xFFFF, 1, 1, 0x0000)
|
|
#define check_crc16_ccitt(data, len) check_crc(data, len, 16, 0x1021, 0x0000, 1, 1, 0x0000)
|
|
#define check_crc16_ccitt_false(data, len) check_crc(data, len, 16, 0x1021, 0xFFFF, 0, 0, 0x0000)
|
|
#define check_crc16_x25(data, len) check_crc(data, len, 16, 0x1021, 0xFFFF, 1, 1, 0xFFFF)
|
|
#define check_crc16_xmodem(data, len) check_crc(data, len, 16, 0x1021, 0x0000, 0, 0, 0x0000)
|
|
#define check_crc16_dnp(data, len) check_crc(data, len, 16, 0x3D65, 0x0000, 1, 1, 0xFFFF)
|
|
#define check_crc32(data, len) check_crc(data, len, 32, 0x04C11DB7, 0xFFFFFFFF, 1, 1, 0xFFFFFFFF)
|
|
#define check_crc32_mpeg_2(data, len) check_crc(data, len, 32, 0x04C11DB7, 0xFFFFFFFF, 0, 0, 0x00000000)
|
|
```
|
|
|
|
### Standard CRC
|
|
|
|
Although the above general CRC can also implement standard CRC, the calculation efficiency will inevitably decrease. The following is the proprietary implementation based on standard CRC.
|
|
```c
|
|
uint8_t crc4_itu(uint8_t* data, uint32_t len);
|
|
uint8_t crc5_epc(uint8_t* data, uint32_t len);
|
|
uint8_t crc5_itu(uint8_t* data, uint32_t len);
|
|
uint8_t crc5_usb(uint8_t* data, uint32_t len);
|
|
uint8_t crc6_itu(uint8_t* data, uint32_t len);
|
|
uint8_t crc7_mmc(uint8_t* data, uint32_t len);
|
|
uint8_t crc8(uint8_t* data, uint32_t len);
|
|
uint8_t crc8_itu(uint8_t* data, uint32_t len);
|
|
uint8_t crc8_rohc(uint8_t* data, uint32_t len);
|
|
uint8_t crc8_maxim(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_ibm(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_maxim(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_usb(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_modbus(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_ccitt(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_ccitt_false(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_x25(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_xmodem(uint8_t* data, uint32_t len);
|
|
uint16_t crc16_dnp(uint8_t* data, uint32_t len);
|
|
uint32_t crc32(uint8_t* data, uint32_t len);
|
|
uint32_t crc32_mpeg_2(uint8_t* data, uint32_t len);
|
|
```
|