2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
[![Arduino CI](https://github.com/RobTillaart/CRC/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
2021-10-27 07:42:30 -04:00
|
|
|
[![Arduino-lint](https://github.com/RobTillaart/CRC/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/CRC/actions/workflows/arduino-lint.yml)
|
|
|
|
[![JSON check](https://github.com/RobTillaart/CRC/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/CRC/actions/workflows/jsoncheck.yml)
|
2021-01-29 06:31:58 -05:00
|
|
|
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/CRC/blob/master/LICENSE)
|
|
|
|
[![GitHub release](https://img.shields.io/github/release/RobTillaart/CRC.svg?maxAge=3600)](https://github.com/RobTillaart/CRC/releases)
|
|
|
|
|
|
|
|
|
|
|
|
# CRC
|
|
|
|
|
2022-01-26 04:27:58 -05:00
|
|
|
Arduino library with CRC8, CRC12, CRC16, CRC32 and CRC64 functions.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
## Description
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
Goal of this library is to have a flexible and portable set of generic
|
2021-12-14 14:22:40 -05:00
|
|
|
CRC functions and classes.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
The CRCx classes have a number of added values.
|
|
|
|
Most important is that they allow one to verify intermediate CRC values.
|
|
|
|
This is useful if one sends a "train of packets" which include a CRC so far.
|
|
|
|
This detects both errors in one single packet but also optional missing packets,
|
2022-05-20 03:04:29 -04:00
|
|
|
or even injected packets.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
Another trick one can do with the class CRCx is to change the polynome or
|
2022-05-20 03:04:29 -04:00
|
|
|
the reverse flag runtime during the process. This makes it harder to imitate.
|
2021-04-07 07:31:22 -04:00
|
|
|
|
|
|
|
Furthermore the class allows to add values in single steps and continue too.
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
Finally the class version gives more readable code (IMHO) as the parameters
|
2021-12-14 14:22:40 -05:00
|
|
|
are explicitly set.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
**Note** the classes have same names as the static functions, except the class
|
2023-01-17 10:18:12 -05:00
|
|
|
is UPPER case. So **CRC8** is a class and **crc8()** is the function.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-05-20 03:04:29 -04:00
|
|
|
Deeper tech info - https://en.wikipedia.org/wiki/Cyclic_redundancy_check
|
2021-01-29 06:31:58 -05:00
|
|
|
and many other websites.
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
#### Related
|
|
|
|
|
|
|
|
- https://github.com/RobTillaart/Adler
|
|
|
|
- https://github.com/RobTillaart/CRC
|
|
|
|
- https://github.com/RobTillaart/Fletcher
|
|
|
|
- https://github.com/RobTillaart/LUHN
|
|
|
|
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
## Interface CRC classes
|
|
|
|
|
2022-05-20 03:04:29 -04:00
|
|
|
The interfaces are very similar for CRC8, CRC12, CRC16, CRC32 and CRC64 class.
|
2023-01-17 10:18:12 -05:00
|
|
|
The only difference is the data type for polynome, start- and end-mask,
|
2021-12-14 14:22:40 -05:00
|
|
|
and the returned CRC.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-02-07 08:10:53 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
#### Base
|
2022-01-28 08:56:11 -05:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
Use **\#include "CRC8.h"**
|
|
|
|
|
2022-05-20 03:04:29 -04:00
|
|
|
- **CRC8()** default - parameterless - constructor.
|
|
|
|
- **CRC8(polynome, XORstart, XORend, reverseIn, reverseOut)** Constructor to set all parameters at once.
|
|
|
|
- **void reset()** set all internals to defaults of the **CRC8()** parameterless constructor.
|
2022-02-07 08:10:53 -05:00
|
|
|
- **void restart()** reset internal CRC and count only;
|
|
|
|
reuse values for other e.g polynome, XOR masks and reverse flags.
|
2021-01-29 06:31:58 -05:00
|
|
|
- **void add(value)** add a single value to CRC calculation.
|
2023-01-17 10:18:12 -05:00
|
|
|
- **void add(array, uint16_t length)** add an array of values to the CRC.
|
2022-02-07 08:10:53 -05:00
|
|
|
In case of a warning/error for the array type, use casting to (uint8_t \*).
|
2023-01-17 10:18:12 -05:00
|
|
|
- **uint8_t getCRC()** returns CRC calculated so far. This allows to check the CRC of
|
2021-12-14 14:22:40 -05:00
|
|
|
a really large stream at intermediate moments, e.g. to link multiple packets.
|
|
|
|
- **uint32_t count()** returns number of values added so far. Default 0.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-02-07 08:10:53 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
#### Parameters
|
2022-01-28 08:56:11 -05:00
|
|
|
|
2022-05-20 03:04:29 -04:00
|
|
|
The parameters do not have defaults so the user must set them explicitly.
|
2022-01-28 08:56:11 -05:00
|
|
|
|
|
|
|
- **void setPolynome(polynome)** set polynome, note reset sets a default polynome.
|
|
|
|
- **void setStartXOR(start)** set start-mask, default 0.
|
|
|
|
- **void setEndXOR(end)** set end-mask, default 0.
|
|
|
|
- **void setReverseIn(bool reverseIn)** reverse the bit pattern of input data (MSB vs LSB).
|
|
|
|
- **void setReverseOut(bool reverseOut)** reverse the bit pattern of CRC (MSB vs LSB).
|
|
|
|
- **uint8_t getPolyNome()** return parameter set above or default.
|
|
|
|
- **uint8_t getStartXOR()** return parameter set above or default.
|
|
|
|
- **uint8_t getEndXOR()** return parameter set above or default.
|
|
|
|
- **bool getReverseIn()** return parameter set above or default.
|
|
|
|
- **bool getReverseOut()** return parameter set above or default.
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
#### Power users only
|
2022-02-08 04:10:54 -05:00
|
|
|
|
|
|
|
As CRC calculations of large blocks can take serious time (in milliseconds),
|
|
|
|
the classes call **yield()** after every 256 **add()** calls to keep RTOS
|
2023-01-17 10:18:12 -05:00
|
|
|
environments happy.
|
2022-02-08 04:10:54 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
The following two calls allows one to enable and disable these calls to
|
2022-02-08 04:10:54 -05:00
|
|
|
**yield()** to get optimal performance. The risk is missing context switching
|
|
|
|
to handle interrupts etc. So use at own risk.
|
|
|
|
|
|
|
|
- **void enableYield()** enables the calls to **yield()**.
|
|
|
|
- **void disableYield()** disables the calls to **yield()**.
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
_Note: the static functions in this library also call **yield()** but this
|
2022-02-08 04:10:54 -05:00
|
|
|
cannot be disabled (for now)._
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
_Note: a parameter could be a future option to set the number of adds before
|
2022-05-20 03:04:29 -04:00
|
|
|
**yield()** is called. **setYield(0)** would be disable it._
|
|
|
|
|
2022-02-08 04:10:54 -05:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
### Example snippet
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
A minimal usage only needs:
|
2021-01-29 06:31:58 -05:00
|
|
|
- the constructor, the add() function and the getCRC() function.
|
|
|
|
|
|
|
|
```cpp
|
2021-04-07 07:31:22 -04:00
|
|
|
#include "CRC32.h"
|
|
|
|
...
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
CRC32 crc;
|
|
|
|
...
|
|
|
|
while (Serial.available())
|
|
|
|
{
|
|
|
|
int c = Serial.read();
|
|
|
|
crc.add(c);
|
|
|
|
}
|
|
|
|
Serial.println(crc.getCRC());
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Interface static functions
|
|
|
|
|
|
|
|
Use **\#include "CRC.h"**
|
|
|
|
|
|
|
|
Most functions have a default polynome, same start and end masks, and default there is no reversing.
|
2023-01-17 10:18:12 -05:00
|
|
|
However these parameters allow one to tweak the CRC in all aspects known.
|
|
|
|
In all the examples encountered the reverse flags were set both to false or both to true.
|
|
|
|
For flexibility both parameters are kept available.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2021-12-14 14:22:40 -05:00
|
|
|
- **uint8_t crc8(array, length, polynome = 0xD5, start = 0, end = 0, reverseIn = false, reverseOut = false)** idem with default polynome.
|
2022-01-26 04:27:58 -05:00
|
|
|
- **uint16_t crc12(array, length, polynome = 0x080D, start = 0, end = 0, reverseIn = false, reverseOut = false)** idem with default polynome.
|
2022-02-08 04:10:54 -05:00
|
|
|
- **uint16_t crc16(array, length, polynome = 0x8001, start = 0, end = 0, reverseIn = false, reverseOut = false)** idem with default polynome.
|
2021-01-29 06:31:58 -05:00
|
|
|
- **uint16_t crc16-CCITT(array, length)** fixed polynome **0x1021**, non zero start / end masks.
|
2021-12-14 14:22:40 -05:00
|
|
|
- **uint32_t crc32(array, length, polynome = 0x04C11DB7, start = 0, end = 0, reverseIn = false, reverseOut = false)** idem with default polynome.
|
2022-02-07 08:10:53 -05:00
|
|
|
- **uint64_t crc64(array, length, polynome = 0x42F0E1EBA9EA3693, start = 0, end = 0, reverseIn = false, reverseOut = false)** - experimental version, no reference found except on Wikipedia.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
Note these functions are limited to one call per block of data.
|
2022-02-08 04:10:54 -05:00
|
|
|
These functions will call **yield()** every 256 bytes to keep RTOS happy.
|
|
|
|
For more flexibility use the specific classes.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
The static CRC functions use fast reverse functions that can be also be
|
2022-02-08 04:10:54 -05:00
|
|
|
used outside CRC context. Their usage is straightforward.
|
2022-01-28 08:56:11 -05:00
|
|
|
|
|
|
|
- **uint8_t reverse8(uint8_t in)** idem.
|
|
|
|
- **uint16_t reverse16(uint16_t in)** idem.
|
|
|
|
- **uint16_t reverse12(uint16_t in)** idem.
|
|
|
|
- **uint32_t reverse32(uint32_t in)** idem.
|
|
|
|
- **uint64_t reverse64(uint64_t in)** idem.
|
|
|
|
|
|
|
|
Reverse12 is based upon reverse16, with a final shift.
|
|
|
|
Other reverses can be created in similar way.
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-02-08 04:10:54 -05:00
|
|
|
## CRC_polynomes.h
|
|
|
|
|
|
|
|
Since version 0.2.1 the file CRC_polynomes.h is added to hold symbolic names for certain polynomes.
|
|
|
|
These can be used in your code too to minimize the number of "magic HEX codes".
|
|
|
|
If standard polynomes are missing, please open an issue and report, with reference.
|
|
|
|
|
|
|
|
|
2021-12-14 14:22:40 -05:00
|
|
|
## Operational
|
|
|
|
|
|
|
|
See examples.
|
|
|
|
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
## Links
|
2021-12-14 14:22:40 -05:00
|
|
|
|
|
|
|
- https://en.wikipedia.org/wiki/Cyclic_redundancy_check - generic background.
|
2022-01-28 08:56:11 -05:00
|
|
|
- http://zorc.breitbandkatze.de/crc.html - online CRC calculator (any base up to 64 is supported.)
|
2021-12-14 14:22:40 -05:00
|
|
|
- https://crccalc.com/ - online CRC calculator to verify.
|
2022-05-20 03:04:29 -04:00
|
|
|
- https://www.lddgo.net/en/encrypt/crc - online CRC calculator
|
2021-12-14 14:22:40 -05:00
|
|
|
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
## Future
|
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
#### Must
|
|
|
|
|
|
|
|
|
|
|
|
#### Should
|
|
|
|
|
|
|
|
- add examples.
|
2022-01-28 08:56:11 -05:00
|
|
|
- example showing multiple packages of data linked by their CRC.
|
2023-01-17 10:18:12 -05:00
|
|
|
sort of "blockchain"
|
|
|
|
|
|
|
|
|
|
|
|
#### Could
|
|
|
|
|
2022-05-20 03:04:29 -04:00
|
|
|
- table versions for performance? (performance - memory discussion).
|
2021-01-29 06:31:58 -05:00
|
|
|
- stream version - 4 classes class?
|
2022-02-07 08:10:53 -05:00
|
|
|
- **setCRC(value)** to be able to pick up where one left ?
|
|
|
|
- can be done with **setStartXOR()**
|
2022-05-20 03:04:29 -04:00
|
|
|
- needs **getRawCRC()** without reverse and end mask
|
2023-01-17 10:18:12 -05:00
|
|
|
- Think about default parameters for constructor **CRC8(polynome, XORstart, XORend, reverseIn, reverseOut)**
|
2022-05-20 03:04:29 -04:00
|
|
|
- same as reset so constructors merge? Note the CRC-functions do have defaults too.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
#### Exotic CRC's ?
|
|
|
|
|
|
|
|
- **CRC1()** // parity :)
|
2021-12-14 14:22:40 -05:00
|
|
|
- **CRC4(array, length, polynome, start, end, reverseIn, reverseOut)** nibbles?
|
2023-01-17 10:18:12 -05:00
|
|
|
- default polynome 0x03 ITU
|
2022-02-07 08:10:53 -05:00
|
|
|
- One CRC() with #bits as parameter?
|
2023-01-17 10:18:12 -05:00
|
|
|
- up to 64 bit for all missing ones?
|
2022-02-07 08:10:53 -05:00
|
|
|
- performance penalty
|
2022-05-20 03:04:29 -04:00
|
|
|
- One CRC() template class?
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-02-07 08:10:53 -05:00
|
|
|
#### Won't
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-02-07 08:10:53 -05:00
|
|
|
- add a dump(Stream = Serial) to see all the settings at once.
|
|
|
|
user can access parameters, so no need.
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2023-01-17 10:18:12 -05:00
|
|
|
|