A Header only, constexpr
/ compile time small-table based CRC library.
Currently only supporting:
- C++20 and above
- C++17 using a fall back static table generator pattern
Unfortunately older C++ standards will not allow the complex statements in
constexpr
functions.
This library implements most of the common CRC checks from 8 to 64 bits.
The calculation is performed using a compile time generated lookup table with only 16 entries (by default) to minimise memory footprint - this is designed for embedded systems where RAM and program memory are at a premium.
If you are able to provide data to the CRC at compile time, the entire CRC is able to be computed at compile time.
This library is available through Conan.
Simply create an instance of the correct algorithm type, and continually
update()
it with bytes. Call final()
to get the CRC result.
If you wish to reuse the crc object, you can call reset()
to initialise it
again.
#include "crc_cpp.h"
[[nodiscard]] constexpr auto compute_crc16ccit(std::vector<char> const &message)
{
crc_cpp::crc16_ccit crc;
for(auto c : message) {
crc.update(c);
}
return crc.final();
}
int main()
{
std::vector<char> const message{'1', '2', '3', '4', '5', '6', '7', '8', '9'};
return 0x29B1 == compute_crc16ccit(message);
}
For each different CRC you use in the program, you will get a new table generated as they all will contain different values.
By default the implementation will select the small
implementation, a
4-bit (16 entry table) and process each byte value as 2 nibbles.
However the crc_cpp library also supports a tiny
and large
implementation.
Implementation | Bits | Table Size |
---|---|---|
crc_cpp::tiny::* |
2 | 4 entries |
crc_cpp::small::* |
4 | 16 entries |
crc_cpp::large::* |
8 | 256 entries |
Where the *
is replaced with the name of the CRC algorithm. See
inlcude/crc_cpp.h for the full list of supported
algorithms.
The bits column indicates how many bits of each byte is processed in a single step. 8 bits means the entire bytes is used in a single step. 4 bits means that we process a nibble (4 bits) at a time, and so on.
Each entry in the table is the size of the CRC register (8, 16, 32 or 64 bits).
If you have a CRC algorithm that isn't already baked in, feel free to define your own:
// Don't use this, seriously.. This is not a real polynomial :)
class mycrc : public crc_cpp::impl::crc<
// size, polynomial, initial, final xor, reverse?
crc_cpp::impl::crc_algorithm<uint32_t, 0xDEADBEEF, 0x00C0DE00, 0x00000000, false>,
// Select table size
crc_cpp::table_size::small
>{};
Then just use it like any other one.
If the reverse parameter is false
, the bits are rotated through the register
MSB to LSB (rotate left). If it is true
the reverse happens and bits are shifted through
LSB to MSB (rotate right).
- crc8
- crc8_cdma2000
- crc8_darc
- crc8_dvbs2
- crc8_ebu
- crc8_icode
- crc8_itu
- crc8_maxim
- crc8_rohc
- crc8_wcdma
- crc16_ccit
- crc16_arc
- crc16_augccit
- crc16_buypass
- crc16_cdma2000
- crc16_dds110
- crc16_dectr
- crc16_dectx
- crc16_dnp
- crc16_en13757
- crc16_genibus
- crc16_maxim
- crc16_mcrf4xx
- crc16_riello
- crc16_t10dif
- crc16_teledisk
- crc16_tms37157
- crc16_usb
- crc16_a
- crc16_kermit
- crc16_modbus
- crc16_x25
- crc16_xmodem
- crc32
- crc32_bzip2
- crc32_c
- crc32_d
- crc32_mpeg2
- crc32_posix
- crc32_q
- crc32_jamcrc
- crc32_xfer
- crc64_ecma
Support is only provided for CRC algorithms with a register size of 8, 16, 32 or 64 bits.
Things to work on in the future:
- Try to back-port to older C++ standards (help appreciated)