Program Listing for File crc.c¶

↰ Return to documentation for file (software/shared/crc/src/crc.c)

/*
The MIT License (MIT)

Copyright (c) 2026 James Nichol

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
#include <crc.h>
#include <stdbool.h>

static const uint8_t crc8_lookup_0x07[] = {
    0x00,
    0x07,
    0x0e,
    0x09,
    0x1c,
    0x1b,
    0x12,
    0x15,
    0x38,
    0x3f,
    0x36,
    0x31,
    0x24,
    0x23,
    0x2a,
    0x2d,
    0x70,
    0x77,
    0x7e,
    0x79,
    0x6c,
    0x6b,
    0x62,
    0x65,
    0x48,
    0x4f,
    0x46,
    0x41,
    0x54,
    0x53,
    0x5a,
    0x5d,
    0xe0,
    0xe7,
    0xee,
    0xe9,
    0xfc,
    0xfb,
    0xf2,
    0xf5,
    0xd8,
    0xdf,
    0xd6,
    0xd1,
    0xc4,
    0xc3,
    0xca,
    0xcd,
    0x90,
    0x97,
    0x9e,
    0x99,
    0x8c,
    0x8b,
    0x82,
    0x85,
    0xa8,
    0xaf,
    0xa6,
    0xa1,
    0xb4,
    0xb3,
    0xba,
    0xbd,
    0xc7,
    0xc0,
    0xc9,
    0xce,
    0xdb,
    0xdc,
    0xd5,
    0xd2,
    0xff,
    0xf8,
    0xf1,
    0xf6,
    0xe3,
    0xe4,
    0xed,
    0xea,
    0xb7,
    0xb0,
    0xb9,
    0xbe,
    0xab,
    0xac,
    0xa5,
    0xa2,
    0x8f,
    0x88,
    0x81,
    0x86,
    0x93,
    0x94,
    0x9d,
    0x9a,
    0x27,
    0x20,
    0x29,
    0x2e,
    0x3b,
    0x3c,
    0x35,
    0x32,
    0x1f,
    0x18,
    0x11,
    0x16,
    0x03,
    0x04,
    0x0d,
    0x0a,
    0x57,
    0x50,
    0x59,
    0x5e,
    0x4b,
    0x4c,
    0x45,
    0x42,
    0x6f,
    0x68,
    0x61,
    0x66,
    0x73,
    0x74,
    0x7d,
    0x7a,
    0x89,
    0x8e,
    0x87,
    0x80,
    0x95,
    0x92,
    0x9b,
    0x9c,
    0xb1,
    0xb6,
    0xbf,
    0xb8,
    0xad,
    0xaa,
    0xa3,
    0xa4,
    0xf9,
    0xfe,
    0xf7,
    0xf0,
    0xe5,
    0xe2,
    0xeb,
    0xec,
    0xc1,
    0xc6,
    0xcf,
    0xc8,
    0xdd,
    0xda,
    0xd3,
    0xd4,
    0x69,
    0x6e,
    0x67,
    0x60,
    0x75,
    0x72,
    0x7b,
    0x7c,
    0x51,
    0x56,
    0x5f,
    0x58,
    0x4d,
    0x4a,
    0x43,
    0x44,
    0x19,
    0x1e,
    0x17,
    0x10,
    0x05,
    0x02,
    0x0b,
    0x0c,
    0x21,
    0x26,
    0x2f,
    0x28,
    0x3d,
    0x3a,
    0x33,
    0x34,
    0x4e,
    0x49,
    0x40,
    0x47,
    0x52,
    0x55,
    0x5c,
    0x5b,
    0x76,
    0x71,
    0x78,
    0x7f,
    0x6a,
    0x6d,
    0x64,
    0x63,
    0x3e,
    0x39,
    0x30,
    0x37,
    0x22,
    0x25,
    0x2c,
    0x2b,
    0x06,
    0x01,
    0x08,
    0x0f,
    0x1a,
    0x1d,
    0x14,
    0x13,
    0xae,
    0xa9,
    0xa0,
    0xa7,
    0xb2,
    0xb5,
    0xbc,
    0xbb,
    0x96,
    0x91,
    0x98,
    0x9f,
    0x8a,
    0x8d,
    0x84,
    0x83,
    0xde,
    0xd9,
    0xd0,
    0xd7,
    0xc2,
    0xc5,
    0xcc,
    0xcb,
    0xe6,
    0xe1,
    0xe8,
    0xef,
    0xfa,
    0xfd,
    0xf4,
    0xf3,
};
static const uint8_t crc8_lookup_0x31[] = {
    0x00,
    0x31,
    0x62,
    0x53,
    0xC4,
    0xF5,
    0xA6,
    0x97,
    0xB9,
    0x88,
    0xDB,
    0xEA,
    0x7D,
    0x4C,
    0x1F,
    0x2E,
    0x43,
    0x72,
    0x21,
    0x10,
    0x87,
    0xB6,
    0xE5,
    0xD4,
    0xFA,
    0xCB,
    0x98,
    0xA9,
    0x3E,
    0x0F,
    0x5C,
    0x6D,
    0x86,
    0xB7,
    0xE4,
    0xD5,
    0x42,
    0x73,
    0x20,
    0x11,
    0x3F,
    0x0E,
    0x5D,
    0x6C,
    0xFB,
    0xCA,
    0x99,
    0xA8,
    0xC5,
    0xF4,
    0xA7,
    0x96,
    0x01,
    0x30,
    0x63,
    0x52,
    0x7C,
    0x4D,
    0x1E,
    0x2F,
    0xB8,
    0x89,
    0xDA,
    0xEB,
    0x3D,
    0x0C,
    0x5F,
    0x6E,
    0xF9,
    0xC8,
    0x9B,
    0xAA,
    0x84,
    0xB5,
    0xE6,
    0xD7,
    0x40,
    0x71,
    0x22,
    0x13,
    0x7E,
    0x4F,
    0x1C,
    0x2D,
    0xBA,
    0x8B,
    0xD8,
    0xE9,
    0xC7,
    0xF6,
    0xA5,
    0x94,
    0x03,
    0x32,
    0x61,
    0x50,
    0xBB,
    0x8A,
    0xD9,
    0xE8,
    0x7F,
    0x4E,
    0x1D,
    0x2C,
    0x02,
    0x33,
    0x60,
    0x51,
    0xC6,
    0xF7,
    0xA4,
    0x95,
    0xF8,
    0xC9,
    0x9A,
    0xAB,
    0x3C,
    0x0D,
    0x5E,
    0x6F,
    0x41,
    0x70,
    0x23,
    0x12,
    0x85,
    0xB4,
    0xE7,
    0xD6,
    0x7A,
    0x4B,
    0x18,
    0x29,
    0xBE,
    0x8F,
    0xDC,
    0xED,
    0xC3,
    0xF2,
    0xA1,
    0x90,
    0x07,
    0x36,
    0x65,
    0x54,
    0x39,
    0x08,
    0x5B,
    0x6A,
    0xFD,
    0xCC,
    0x9F,
    0xAE,
    0x80,
    0xB1,
    0xE2,
    0xD3,
    0x44,
    0x75,
    0x26,
    0x17,
    0xFC,
    0xCD,
    0x9E,
    0xAF,
    0x38,
    0x09,
    0x5A,
    0x6B,
    0x45,
    0x74,
    0x27,
    0x16,
    0x81,
    0xB0,
    0xE3,
    0xD2,
    0xBF,
    0x8E,
    0xDD,
    0xEC,
    0x7B,
    0x4A,
    0x19,
    0x28,
    0x06,
    0x37,
    0x64,
    0x55,
    0xC2,
    0xF3,
    0xA0,
    0x91,
    0x47,
    0x76,
    0x25,
    0x14,
    0x83,
    0xB2,
    0xE1,
    0xD0,
    0xFE,
    0xCF,
    0x9C,
    0xAD,
    0x3A,
    0x0B,
    0x58,
    0x69,
    0x04,
    0x35,
    0x66,
    0x57,
    0xC0,
    0xF1,
    0xA2,
    0x93,
    0xBD,
    0x8C,
    0xDF,
    0xEE,
    0x79,
    0x48,
    0x1B,
    0x2A,
    0xC1,
    0xF0,
    0xA3,
    0x92,
    0x05,
    0x34,
    0x67,
    0x56,
    0x78,
    0x49,
    0x1A,
    0x2B,
    0xBC,
    0x8D,
    0xDE,
    0xEF,
    0x82,
    0xB3,
    0xE0,
    0xD1,
    0x46,
    0x77,
    0x24,
    0x15,
    0x3B,
    0x0A,
    0x59,
    0x68,
    0xFF,
    0xCE,
    0x9D,
    0xAC,
};
static const uint8_t crc8_lookup_reflected_0x31[] = {
    0x00,
    0x5e,
    0xbc,
    0xe2,
    0x61,
    0x3f,
    0xdd,
    0x83,
    0xc2,
    0x9c,
    0x7e,
    0x20,
    0xa3,
    0xfd,
    0x1f,
    0x41,
    0x9d,
    0xc3,
    0x21,
    0x7f,
    0xfc,
    0xa2,
    0x40,
    0x1e,
    0x5f,
    0x01,
    0xe3,
    0xbd,
    0x3e,
    0x60,
    0x82,
    0xdc,
    0x23,
    0x7d,
    0x9f,
    0xc1,
    0x42,
    0x1c,
    0xfe,
    0xa0,
    0xe1,
    0xbf,
    0x5d,
    0x03,
    0x80,
    0xde,
    0x3c,
    0x62,
    0xbe,
    0xe0,
    0x02,
    0x5c,
    0xdf,
    0x81,
    0x63,
    0x3d,
    0x7c,
    0x22,
    0xc0,
    0x9e,
    0x1d,
    0x43,
    0xa1,
    0xff,
    0x46,
    0x18,
    0xfa,
    0xa4,
    0x27,
    0x79,
    0x9b,
    0xc5,
    0x84,
    0xda,
    0x38,
    0x66,
    0xe5,
    0xbb,
    0x59,
    0x07,
    0xdb,
    0x85,
    0x67,
    0x39,
    0xba,
    0xe4,
    0x06,
    0x58,
    0x19,
    0x47,
    0xa5,
    0xfb,
    0x78,
    0x26,
    0xc4,
    0x9a,
    0x65,
    0x3b,
    0xd9,
    0x87,
    0x04,
    0x5a,
    0xb8,
    0xe6,
    0xa7,
    0xf9,
    0x1b,
    0x45,
    0xc6,
    0x98,
    0x7a,
    0x24,
    0xf8,
    0xa6,
    0x44,
    0x1a,
    0x99,
    0xc7,
    0x25,
    0x7b,
    0x3a,
    0x64,
    0x86,
    0xd8,
    0x5b,
    0x05,
    0xe7,
    0xb9,
    0x8c,
    0xd2,
    0x30,
    0x6e,
    0xed,
    0xb3,
    0x51,
    0x0f,
    0x4e,
    0x10,
    0xf2,
    0xac,
    0x2f,
    0x71,
    0x93,
    0xcd,
    0x11,
    0x4f,
    0xad,
    0xf3,
    0x70,
    0x2e,
    0xcc,
    0x92,
    0xd3,
    0x8d,
    0x6f,
    0x31,
    0xb2,
    0xec,
    0x0e,
    0x50,
    0xaf,
    0xf1,
    0x13,
    0x4d,
    0xce,
    0x90,
    0x72,
    0x2c,
    0x6d,
    0x33,
    0xd1,
    0x8f,
    0x0c,
    0x52,
    0xb0,
    0xee,
    0x32,
    0x6c,
    0x8e,
    0xd0,
    0x53,
    0x0d,
    0xef,
    0xb1,
    0xf0,
    0xae,
    0x4c,
    0x12,
    0x91,
    0xcf,
    0x2d,
    0x73,
    0xca,
    0x94,
    0x76,
    0x28,
    0xab,
    0xf5,
    0x17,
    0x49,
    0x08,
    0x56,
    0xb4,
    0xea,
    0x69,
    0x37,
    0xd5,
    0x8b,
    0x57,
    0x09,
    0xeb,
    0xb5,
    0x36,
    0x68,
    0x8a,
    0xd4,
    0x95,
    0xcb,
    0x29,
    0x77,
    0xf4,
    0xaa,
    0x48,
    0x16,
    0xe9,
    0xb7,
    0x55,
    0x0b,
    0x88,
    0xd6,
    0x34,
    0x6a,
    0x2b,
    0x75,
    0x97,
    0xc9,
    0x4a,
    0x14,
    0xf6,
    0xa8,
    0x74,
    0x2a,
    0xc8,
    0x96,
    0x15,
    0x4b,
    0xa9,
    0xf7,
    0xb6,
    0xe8,
    0x0a,
    0x54,
    0xd7,
    0x89,
    0x6b,
    0x35,
};

static const uint16_t crc16_lookup_0x1021[] = {
    0x0000,
    0x1021,
    0x2042,
    0x3063,
    0x4084,
    0x50a5,
    0x60c6,
    0x70e7,
    0x8108,
    0x9129,
    0xa14a,
    0xb16b,
    0xc18c,
    0xd1ad,
    0xe1ce,
    0xf1ef,
    0x1231,
    0x0210,
    0x3273,
    0x2252,
    0x52b5,
    0x4294,
    0x72f7,
    0x62d6,
    0x9339,
    0x8318,
    0xb37b,
    0xa35a,
    0xd3bd,
    0xc39c,
    0xf3ff,
    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,
    0x8948,
    0x9969,
    0xa90a,
    0xb92b,
    0x5af5,
    0x4ad4,
    0x7ab7,
    0x6a96,
    0x1a71,
    0x0a50,
    0x3a33,
    0x2a12,
    0xdbfd,
    0xcbdc,
    0xfbbf,
    0xeb9e,
    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,
    0x5004,
    0x4025,
    0x7046,
    0x6067,
    0x83b9,
    0x9398,
    0xa3fb,
    0xb3da,
    0xc33d,
    0xd31c,
    0xe37f,
    0xf35e,
    0x02b1,
    0x1290,
    0x22f3,
    0x32d2,
    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,
    0x4865,
    0x7806,
    0x6827,
    0x18c0,
    0x08e1,
    0x3882,
    0x28a3,
    0xcb7d,
    0xdb5c,
    0xeb3f,
    0xfb1e,
    0x8bf9,
    0x9bd8,
    0xabbb,
    0xbb9a,
    0x4a75,
    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,
};
static const uint16_t crc16_lookup_reflected_0x8005[] = {
    0x0000,
    0xc0c1,
    0xc181,
    0x0140,
    0xc301,
    0x03c0,
    0x0280,
    0xc241,
    0xc601,
    0x06c0,
    0x0780,
    0xc741,
    0x0500,
    0xc5c1,
    0xc481,
    0x0440,
    0xcc01,
    0x0cc0,
    0x0d80,
    0xcd41,
    0x0f00,
    0xcfc1,
    0xce81,
    0x0e40,
    0x0a00,
    0xcac1,
    0xcb81,
    0x0b40,
    0xc901,
    0x09c0,
    0x0880,
    0xc841,
    0xd801,
    0x18c0,
    0x1980,
    0xd941,
    0x1b00,
    0xdbc1,
    0xda81,
    0x1a40,
    0x1e00,
    0xdec1,
    0xdf81,
    0x1f40,
    0xdd01,
    0x1dc0,
    0x1c80,
    0xdc41,
    0x1400,
    0xd4c1,
    0xd581,
    0x1540,
    0xd701,
    0x17c0,
    0x1680,
    0xd641,
    0xd201,
    0x12c0,
    0x1380,
    0xd341,
    0x1100,
    0xd1c1,
    0xd081,
    0x1040,
    0xf001,
    0x30c0,
    0x3180,
    0xf141,
    0x3300,
    0xf3c1,
    0xf281,
    0x3240,
    0x3600,
    0xf6c1,
    0xf781,
    0x3740,
    0xf501,
    0x35c0,
    0x3480,
    0xf441,
    0x3c00,
    0xfcc1,
    0xfd81,
    0x3d40,
    0xff01,
    0x3fc0,
    0x3e80,
    0xfe41,
    0xfa01,
    0x3ac0,
    0x3b80,
    0xfb41,
    0x3900,
    0xf9c1,
    0xf881,
    0x3840,
    0x2800,
    0xe8c1,
    0xe981,
    0x2940,
    0xeb01,
    0x2bc0,
    0x2a80,
    0xea41,
    0xee01,
    0x2ec0,
    0x2f80,
    0xef41,
    0x2d00,
    0xedc1,
    0xec81,
    0x2c40,
    0xe401,
    0x24c0,
    0x2580,
    0xe541,
    0x2700,
    0xe7c1,
    0xe681,
    0x2640,
    0x2200,
    0xe2c1,
    0xe381,
    0x2340,
    0xe101,
    0x21c0,
    0x2080,
    0xe041,
    0xa001,
    0x60c0,
    0x6180,
    0xa141,
    0x6300,
    0xa3c1,
    0xa281,
    0x6240,
    0x6600,
    0xa6c1,
    0xa781,
    0x6740,
    0xa501,
    0x65c0,
    0x6480,
    0xa441,
    0x6c00,
    0xacc1,
    0xad81,
    0x6d40,
    0xaf01,
    0x6fc0,
    0x6e80,
    0xae41,
    0xaa01,
    0x6ac0,
    0x6b80,
    0xab41,
    0x6900,
    0xa9c1,
    0xa881,
    0x6840,
    0x7800,
    0xb8c1,
    0xb981,
    0x7940,
    0xbb01,
    0x7bc0,
    0x7a80,
    0xba41,
    0xbe01,
    0x7ec0,
    0x7f80,
    0xbf41,
    0x7d00,
    0xbdc1,
    0xbc81,
    0x7c40,
    0xb401,
    0x74c0,
    0x7580,
    0xb541,
    0x7700,
    0xb7c1,
    0xb681,
    0x7640,
    0x7200,
    0xb2c1,
    0xb381,
    0x7340,
    0xb101,
    0x71c0,
    0x7080,
    0xb041,
    0x5000,
    0x90c1,
    0x9181,
    0x5140,
    0x9301,
    0x53c0,
    0x5280,
    0x9241,
    0x9601,
    0x56c0,
    0x5780,
    0x9741,
    0x5500,
    0x95c1,
    0x9481,
    0x5440,
    0x9c01,
    0x5cc0,
    0x5d80,
    0x9d41,
    0x5f00,
    0x9fc1,
    0x9e81,
    0x5e40,
    0x5a00,
    0x9ac1,
    0x9b81,
    0x5b40,
    0x9901,
    0x59c0,
    0x5880,
    0x9841,
    0x8801,
    0x48c0,
    0x4980,
    0x8941,
    0x4b00,
    0x8bc1,
    0x8a81,
    0x4a40,
    0x4e00,
    0x8ec1,
    0x8f81,
    0x4f40,
    0x8d01,
    0x4dc0,
    0x4c80,
    0x8c41,
    0x4400,
    0x84c1,
    0x8581,
    0x4540,
    0x8701,
    0x47c0,
    0x4680,
    0x8641,
    0x8201,
    0x42c0,
    0x4380,
    0x8341,
    0x4100,
    0x81c1,
    0x8081,
    0x4040,
};

static const uint32_t crc32_lookup_0x04C11DB7[] = {
    0x00000000,
    0x04c11db7,
    0x09823b6e,
    0x0d4326d9,
    0x130476dc,
    0x17c56b6b,
    0x1a864db2,
    0x1e475005,
    0x2608edb8,
    0x22c9f00f,
    0x2f8ad6d6,
    0x2b4bcb61,
    0x350c9b64,
    0x31cd86d3,
    0x3c8ea00a,
    0x384fbdbd,
    0x4c11db70,
    0x48d0c6c7,
    0x4593e01e,
    0x4152fda9,
    0x5f15adac,
    0x5bd4b01b,
    0x569796c2,
    0x52568b75,
    0x6a1936c8,
    0x6ed82b7f,
    0x639b0da6,
    0x675a1011,
    0x791d4014,
    0x7ddc5da3,
    0x709f7b7a,
    0x745e66cd,
    0x9823b6e0,
    0x9ce2ab57,
    0x91a18d8e,
    0x95609039,
    0x8b27c03c,
    0x8fe6dd8b,
    0x82a5fb52,
    0x8664e6e5,
    0xbe2b5b58,
    0xbaea46ef,
    0xb7a96036,
    0xb3687d81,
    0xad2f2d84,
    0xa9ee3033,
    0xa4ad16ea,
    0xa06c0b5d,
    0xd4326d90,
    0xd0f37027,
    0xddb056fe,
    0xd9714b49,
    0xc7361b4c,
    0xc3f706fb,
    0xceb42022,
    0xca753d95,
    0xf23a8028,
    0xf6fb9d9f,
    0xfbb8bb46,
    0xff79a6f1,
    0xe13ef6f4,
    0xe5ffeb43,
    0xe8bccd9a,
    0xec7dd02d,
    0x34867077,
    0x30476dc0,
    0x3d044b19,
    0x39c556ae,
    0x278206ab,
    0x23431b1c,
    0x2e003dc5,
    0x2ac12072,
    0x128e9dcf,
    0x164f8078,
    0x1b0ca6a1,
    0x1fcdbb16,
    0x018aeb13,
    0x054bf6a4,
    0x0808d07d,
    0x0cc9cdca,
    0x7897ab07,
    0x7c56b6b0,
    0x71159069,
    0x75d48dde,
    0x6b93dddb,
    0x6f52c06c,
    0x6211e6b5,
    0x66d0fb02,
    0x5e9f46bf,
    0x5a5e5b08,
    0x571d7dd1,
    0x53dc6066,
    0x4d9b3063,
    0x495a2dd4,
    0x44190b0d,
    0x40d816ba,
    0xaca5c697,
    0xa864db20,
    0xa527fdf9,
    0xa1e6e04e,
    0xbfa1b04b,
    0xbb60adfc,
    0xb6238b25,
    0xb2e29692,
    0x8aad2b2f,
    0x8e6c3698,
    0x832f1041,
    0x87ee0df6,
    0x99a95df3,
    0x9d684044,
    0x902b669d,
    0x94ea7b2a,
    0xe0b41de7,
    0xe4750050,
    0xe9362689,
    0xedf73b3e,
    0xf3b06b3b,
    0xf771768c,
    0xfa325055,
    0xfef34de2,
    0xc6bcf05f,
    0xc27dede8,
    0xcf3ecb31,
    0xcbffd686,
    0xd5b88683,
    0xd1799b34,
    0xdc3abded,
    0xd8fba05a,
    0x690ce0ee,
    0x6dcdfd59,
    0x608edb80,
    0x644fc637,
    0x7a089632,
    0x7ec98b85,
    0x738aad5c,
    0x774bb0eb,
    0x4f040d56,
    0x4bc510e1,
    0x46863638,
    0x42472b8f,
    0x5c007b8a,
    0x58c1663d,
    0x558240e4,
    0x51435d53,
    0x251d3b9e,
    0x21dc2629,
    0x2c9f00f0,
    0x285e1d47,
    0x36194d42,
    0x32d850f5,
    0x3f9b762c,
    0x3b5a6b9b,
    0x0315d626,
    0x07d4cb91,
    0x0a97ed48,
    0x0e56f0ff,
    0x1011a0fa,
    0x14d0bd4d,
    0x19939b94,
    0x1d528623,
    0xf12f560e,
    0xf5ee4bb9,
    0xf8ad6d60,
    0xfc6c70d7,
    0xe22b20d2,
    0xe6ea3d65,
    0xeba91bbc,
    0xef68060b,
    0xd727bbb6,
    0xd3e6a601,
    0xdea580d8,
    0xda649d6f,
    0xc423cd6a,
    0xc0e2d0dd,
    0xcda1f604,
    0xc960ebb3,
    0xbd3e8d7e,
    0xb9ff90c9,
    0xb4bcb610,
    0xb07daba7,
    0xae3afba2,
    0xaafbe615,
    0xa7b8c0cc,
    0xa379dd7b,
    0x9b3660c6,
    0x9ff77d71,
    0x92b45ba8,
    0x9675461f,
    0x8832161a,
    0x8cf30bad,
    0x81b02d74,
    0x857130c3,
    0x5d8a9099,
    0x594b8d2e,
    0x5408abf7,
    0x50c9b640,
    0x4e8ee645,
    0x4a4ffbf2,
    0x470cdd2b,
    0x43cdc09c,
    0x7b827d21,
    0x7f436096,
    0x7200464f,
    0x76c15bf8,
    0x68860bfd,
    0x6c47164a,
    0x61043093,
    0x65c52d24,
    0x119b4be9,
    0x155a565e,
    0x18197087,
    0x1cd86d30,
    0x029f3d35,
    0x065e2082,
    0x0b1d065b,
    0x0fdc1bec,
    0x3793a651,
    0x3352bbe6,
    0x3e119d3f,
    0x3ad08088,
    0x2497d08d,
    0x2056cd3a,
    0x2d15ebe3,
    0x29d4f654,
    0xc5a92679,
    0xc1683bce,
    0xcc2b1d17,
    0xc8ea00a0,
    0xd6ad50a5,
    0xd26c4d12,
    0xdf2f6bcb,
    0xdbee767c,
    0xe3a1cbc1,
    0xe760d676,
    0xea23f0af,
    0xeee2ed18,
    0xf0a5bd1d,
    0xf464a0aa,
    0xf9278673,
    0xfde69bc4,
    0x89b8fd09,
    0x8d79e0be,
    0x803ac667,
    0x84fbdbd0,
    0x9abc8bd5,
    0x9e7d9662,
    0x933eb0bb,
    0x97ffad0c,
    0xafb010b1,
    0xab710d06,
    0xa6322bdf,
    0xa2f33668,
    0xbcb4666d,
    0xb8757bda,
    0xb5365d03,
    0xb1f740b4,
};
static const uint32_t crc32_lookup_reflected_0x04C11DB7[] = {
    0x00000000,
    0x77073096,
    0xee0e612c,
    0x990951ba,
    0x076dc419,
    0x706af48f,
    0xe963a535,
    0x9e6495a3,
    0x0edb8832,
    0x79dcb8a4,
    0xe0d5e91e,
    0x97d2d988,
    0x09b64c2b,
    0x7eb17cbd,
    0xe7b82d07,
    0x90bf1d91,
    0x1db71064,
    0x6ab020f2,
    0xf3b97148,
    0x84be41de,
    0x1adad47d,
    0x6ddde4eb,
    0xf4d4b551,
    0x83d385c7,
    0x136c9856,
    0x646ba8c0,
    0xfd62f97a,
    0x8a65c9ec,
    0x14015c4f,
    0x63066cd9,
    0xfa0f3d63,
    0x8d080df5,
    0x3b6e20c8,
    0x4c69105e,
    0xd56041e4,
    0xa2677172,
    0x3c03e4d1,
    0x4b04d447,
    0xd20d85fd,
    0xa50ab56b,
    0x35b5a8fa,
    0x42b2986c,
    0xdbbbc9d6,
    0xacbcf940,
    0x32d86ce3,
    0x45df5c75,
    0xdcd60dcf,
    0xabd13d59,
    0x26d930ac,
    0x51de003a,
    0xc8d75180,
    0xbfd06116,
    0x21b4f4b5,
    0x56b3c423,
    0xcfba9599,
    0xb8bda50f,
    0x2802b89e,
    0x5f058808,
    0xc60cd9b2,
    0xb10be924,
    0x2f6f7c87,
    0x58684c11,
    0xc1611dab,
    0xb6662d3d,
    0x76dc4190,
    0x01db7106,
    0x98d220bc,
    0xefd5102a,
    0x71b18589,
    0x06b6b51f,
    0x9fbfe4a5,
    0xe8b8d433,
    0x7807c9a2,
    0x0f00f934,
    0x9609a88e,
    0xe10e9818,
    0x7f6a0dbb,
    0x086d3d2d,
    0x91646c97,
    0xe6635c01,
    0x6b6b51f4,
    0x1c6c6162,
    0x856530d8,
    0xf262004e,
    0x6c0695ed,
    0x1b01a57b,
    0x8208f4c1,
    0xf50fc457,
    0x65b0d9c6,
    0x12b7e950,
    0x8bbeb8ea,
    0xfcb9887c,
    0x62dd1ddf,
    0x15da2d49,
    0x8cd37cf3,
    0xfbd44c65,
    0x4db26158,
    0x3ab551ce,
    0xa3bc0074,
    0xd4bb30e2,
    0x4adfa541,
    0x3dd895d7,
    0xa4d1c46d,
    0xd3d6f4fb,
    0x4369e96a,
    0x346ed9fc,
    0xad678846,
    0xda60b8d0,
    0x44042d73,
    0x33031de5,
    0xaa0a4c5f,
    0xdd0d7cc9,
    0x5005713c,
    0x270241aa,
    0xbe0b1010,
    0xc90c2086,
    0x5768b525,
    0x206f85b3,
    0xb966d409,
    0xce61e49f,
    0x5edef90e,
    0x29d9c998,
    0xb0d09822,
    0xc7d7a8b4,
    0x59b33d17,
    0x2eb40d81,
    0xb7bd5c3b,
    0xc0ba6cad,
    0xedb88320,
    0x9abfb3b6,
    0x03b6e20c,
    0x74b1d29a,
    0xead54739,
    0x9dd277af,
    0x04db2615,
    0x73dc1683,
    0xe3630b12,
    0x94643b84,
    0x0d6d6a3e,
    0x7a6a5aa8,
    0xe40ecf0b,
    0x9309ff9d,
    0x0a00ae27,
    0x7d079eb1,
    0xf00f9344,
    0x8708a3d2,
    0x1e01f268,
    0x6906c2fe,
    0xf762575d,
    0x806567cb,
    0x196c3671,
    0x6e6b06e7,
    0xfed41b76,
    0x89d32be0,
    0x10da7a5a,
    0x67dd4acc,
    0xf9b9df6f,
    0x8ebeeff9,
    0x17b7be43,
    0x60b08ed5,
    0xd6d6a3e8,
    0xa1d1937e,
    0x38d8c2c4,
    0x4fdff252,
    0xd1bb67f1,
    0xa6bc5767,
    0x3fb506dd,
    0x48b2364b,
    0xd80d2bda,
    0xaf0a1b4c,
    0x36034af6,
    0x41047a60,
    0xdf60efc3,
    0xa867df55,
    0x316e8eef,
    0x4669be79,
    0xcb61b38c,
    0xbc66831a,
    0x256fd2a0,
    0x5268e236,
    0xcc0c7795,
    0xbb0b4703,
    0x220216b9,
    0x5505262f,
    0xc5ba3bbe,
    0xb2bd0b28,
    0x2bb45a92,
    0x5cb36a04,
    0xc2d7ffa7,
    0xb5d0cf31,
    0x2cd99e8b,
    0x5bdeae1d,
    0x9b64c2b0,
    0xec63f226,
    0x756aa39c,
    0x026d930a,
    0x9c0906a9,
    0xeb0e363f,
    0x72076785,
    0x05005713,
    0x95bf4a82,
    0xe2b87a14,
    0x7bb12bae,
    0x0cb61b38,
    0x92d28e9b,
    0xe5d5be0d,
    0x7cdcefb7,
    0x0bdbdf21,
    0x86d3d2d4,
    0xf1d4e242,
    0x68ddb3f8,
    0x1fda836e,
    0x81be16cd,
    0xf6b9265b,
    0x6fb077e1,
    0x18b74777,
    0x88085ae6,
    0xff0f6a70,
    0x66063bca,
    0x11010b5c,
    0x8f659eff,
    0xf862ae69,
    0x616bffd3,
    0x166ccf45,
    0xa00ae278,
    0xd70dd2ee,
    0x4e048354,
    0x3903b3c2,
    0xa7672661,
    0xd06016f7,
    0x4969474d,
    0x3e6e77db,
    0xaed16a4a,
    0xd9d65adc,
    0x40df0b66,
    0x37d83bf0,
    0xa9bcae53,
    0xdebb9ec5,
    0x47b2cf7f,
    0x30b5ffe9,
    0xbdbdf21c,
    0xcabac28a,
    0x53b39330,
    0x24b4a3a6,
    0xbad03605,
    0xcdd70693,
    0x54de5729,
    0x23d967bf,
    0xb3667a2e,
    0xc4614ab8,
    0x5d681b02,
    0x2a6f2b94,
    0xb40bbe37,
    0xc30c8ea1,
    0x5a05df1b,
    0x2d02ef8d,
};
static const uint32_t crc32_C_lookup[] = {
    0x00000000,
    0xf26b8303,
    0xe13b70f7,
    0x1350f3f4,
    0xc79a971f,
    0x35f1141c,
    0x26a1e7e8,
    0xd4ca64eb,
    0x8ad958cf,
    0x78b2dbcc,
    0x6be22838,
    0x9989ab3b,
    0x4d43cfd0,
    0xbf284cd3,
    0xac78bf27,
    0x5e133c24,
    0x105ec76f,
    0xe235446c,
    0xf165b798,
    0x030e349b,
    0xd7c45070,
    0x25afd373,
    0x36ff2087,
    0xc494a384,
    0x9a879fa0,
    0x68ec1ca3,
    0x7bbcef57,
    0x89d76c54,
    0x5d1d08bf,
    0xaf768bbc,
    0xbc267848,
    0x4e4dfb4b,
    0x20bd8ede,
    0xd2d60ddd,
    0xc186fe29,
    0x33ed7d2a,
    0xe72719c1,
    0x154c9ac2,
    0x061c6936,
    0xf477ea35,
    0xaa64d611,
    0x580f5512,
    0x4b5fa6e6,
    0xb93425e5,
    0x6dfe410e,
    0x9f95c20d,
    0x8cc531f9,
    0x7eaeb2fa,
    0x30e349b1,
    0xc288cab2,
    0xd1d83946,
    0x23b3ba45,
    0xf779deae,
    0x05125dad,
    0x1642ae59,
    0xe4292d5a,
    0xba3a117e,
    0x4851927d,
    0x5b016189,
    0xa96ae28a,
    0x7da08661,
    0x8fcb0562,
    0x9c9bf696,
    0x6ef07595,
    0x417b1dbc,
    0xb3109ebf,
    0xa0406d4b,
    0x522bee48,
    0x86e18aa3,
    0x748a09a0,
    0x67dafa54,
    0x95b17957,
    0xcba24573,
    0x39c9c670,
    0x2a993584,
    0xd8f2b687,
    0x0c38d26c,
    0xfe53516f,
    0xed03a29b,
    0x1f682198,
    0x5125dad3,
    0xa34e59d0,
    0xb01eaa24,
    0x42752927,
    0x96bf4dcc,
    0x64d4cecf,
    0x77843d3b,
    0x85efbe38,
    0xdbfc821c,
    0x2997011f,
    0x3ac7f2eb,
    0xc8ac71e8,
    0x1c661503,
    0xee0d9600,
    0xfd5d65f4,
    0x0f36e6f7,
    0x61c69362,
    0x93ad1061,
    0x80fde395,
    0x72966096,
    0xa65c047d,
    0x5437877e,
    0x4767748a,
    0xb50cf789,
    0xeb1fcbad,
    0x197448ae,
    0x0a24bb5a,
    0xf84f3859,
    0x2c855cb2,
    0xdeeedfb1,
    0xcdbe2c45,
    0x3fd5af46,
    0x7198540d,
    0x83f3d70e,
    0x90a324fa,
    0x62c8a7f9,
    0xb602c312,
    0x44694011,
    0x5739b3e5,
    0xa55230e6,
    0xfb410cc2,
    0x092a8fc1,
    0x1a7a7c35,
    0xe811ff36,
    0x3cdb9bdd,
    0xceb018de,
    0xdde0eb2a,
    0x2f8b6829,
    0x82f63b78,
    0x709db87b,
    0x63cd4b8f,
    0x91a6c88c,
    0x456cac67,
    0xb7072f64,
    0xa457dc90,
    0x563c5f93,
    0x082f63b7,
    0xfa44e0b4,
    0xe9141340,
    0x1b7f9043,
    0xcfb5f4a8,
    0x3dde77ab,
    0x2e8e845f,
    0xdce5075c,
    0x92a8fc17,
    0x60c37f14,
    0x73938ce0,
    0x81f80fe3,
    0x55326b08,
    0xa759e80b,
    0xb4091bff,
    0x466298fc,
    0x1871a4d8,
    0xea1a27db,
    0xf94ad42f,
    0x0b21572c,
    0xdfeb33c7,
    0x2d80b0c4,
    0x3ed04330,
    0xccbbc033,
    0xa24bb5a6,
    0x502036a5,
    0x4370c551,
    0xb11b4652,
    0x65d122b9,
    0x97baa1ba,
    0x84ea524e,
    0x7681d14d,
    0x2892ed69,
    0xdaf96e6a,
    0xc9a99d9e,
    0x3bc21e9d,
    0xef087a76,
    0x1d63f975,
    0x0e330a81,
    0xfc588982,
    0xb21572c9,
    0x407ef1ca,
    0x532e023e,
    0xa145813d,
    0x758fe5d6,
    0x87e466d5,
    0x94b49521,
    0x66df1622,
    0x38cc2a06,
    0xcaa7a905,
    0xd9f75af1,
    0x2b9cd9f2,
    0xff56bd19,
    0x0d3d3e1a,
    0x1e6dcdee,
    0xec064eed,
    0xc38d26c4,
    0x31e6a5c7,
    0x22b65633,
    0xd0ddd530,
    0x0417b1db,
    0xf67c32d8,
    0xe52cc12c,
    0x1747422f,
    0x49547e0b,
    0xbb3ffd08,
    0xa86f0efc,
    0x5a048dff,
    0x8ecee914,
    0x7ca56a17,
    0x6ff599e3,
    0x9d9e1ae0,
    0xd3d3e1ab,
    0x21b862a8,
    0x32e8915c,
    0xc083125f,
    0x144976b4,
    0xe622f5b7,
    0xf5720643,
    0x07198540,
    0x590ab964,
    0xab613a67,
    0xb831c993,
    0x4a5a4a90,
    0x9e902e7b,
    0x6cfbad78,
    0x7fab5e8c,
    0x8dc0dd8f,
    0xe330a81a,
    0x115b2b19,
    0x020bd8ed,
    0xf0605bee,
    0x24aa3f05,
    0xd6c1bc06,
    0xc5914ff2,
    0x37faccf1,
    0x69e9f0d5,
    0x9b8273d6,
    0x88d28022,
    0x7ab90321,
    0xae7367ca,
    0x5c18e4c9,
    0x4f48173d,
    0xbd23943e,
    0xf36e6f75,
    0x0105ec76,
    0x12551f82,
    0xe03e9c81,
    0x34f4f86a,
    0xc69f7b69,
    0xd5cf889d,
    0x27a40b9e,
    0x79b737ba,
    0x8bdcb4b9,
    0x988c474d,
    0x6ae7c44e,
    0xbe2da0a5,
    0x4c4623a6,
    0x5f16d052,
    0xad7d5351,
};

static uint8_t crc8_generic(const uint8_t* data, const size_t len, const uint8_t* lookup, const uint8_t init, const bool invert_result)
{
    uint8_t crc = init;

    for (size_t i = 0; i < len; i++)
        crc = lookup[data[i] ^ crc];

    if (invert_result)
        crc = ~crc;
    return crc;
}
uint8_t crc8(const uint8_t* data, const size_t len)
{
    return crc8_generic(data, len, crc8_lookup_0x07, 0x00, false);
}
uint8_t crc8_maxim(const uint8_t* data, const size_t len)
{
    return crc8_generic(data, len, crc8_lookup_reflected_0x31, 0x00, false);
}
uint8_t crc8_sht75(const uint8_t* data, const size_t len)
{
    return crc8_generic(data, len, crc8_lookup_0x31, 0x00, false);
}

static uint16_t crc16_generic(const uint8_t* data, const size_t len, const uint16_t* lookup, const uint16_t init, const bool invert_result)
{
    uint16_t crc = init;

    for (size_t i = 0; i < len; i++)
        crc = (crc << 8) ^ lookup[(crc >> 8) ^ data[i]];

    if (invert_result)
        crc = ~crc;
    return crc;
}

static uint16_t crc16_reflected_generic(const uint8_t* data, const size_t len, const uint16_t* lookup, const uint16_t init, const bool invert_result)
{
    uint16_t crc = init;

    for (size_t i = 0; i < len; i++)
        crc = (crc >> 8) ^ lookup[(data[i] ^ crc) & 0xFF];

    if (invert_result)
        crc = ~crc;
    return crc;
}

uint16_t crc16(const uint8_t* data, const size_t len)
{
    return crc16_reflected_generic(data, len, crc16_lookup_reflected_0x8005, 0x0000, false);
}
uint16_t crc16_ccitt(const uint8_t* data, const size_t len)
{
    return crc16_generic(data, len, crc16_lookup_0x1021, 0x1D0F, false);
}
uint16_t crc16_modbus(const uint8_t* data, const size_t len)
{
    return crc16_reflected_generic(data, len, crc16_lookup_reflected_0x8005, 0xFFFF, false);
}
uint16_t crc16_usb(const uint8_t* data, const size_t len)
{
    return crc16_reflected_generic(data, len, crc16_lookup_reflected_0x8005, 0xFFFF, true);
}
uint16_t crc16_xmodem(const uint8_t* data, const size_t len)
{
    return crc16_generic(data, len, crc16_lookup_0x1021, 0x0000, false);
}

static uint32_t crc32_generic(const uint8_t* data, const size_t len, const uint32_t* lookup, const uint32_t init, const bool invert_result)
{
    uint32_t crc = init;

    for (size_t i = 0; i < len; i++)
        crc = (crc << 8) ^ lookup[((crc >> 24) ^ data[i])];

    if (invert_result)
        crc = ~crc;
    return crc;
}
static uint32_t crc32_reflected_generic(const uint8_t* data, const size_t len, const uint32_t* lookup, const uint32_t init, const bool invert_result)
{
    uint32_t crc = init;

    for (size_t i = 0; i < len; i++)
        crc = (crc >> 8) ^ lookup[(data[i] ^ crc) & 0xFF];

    if (invert_result)
        crc = ~crc;
    return crc;
}

uint32_t crc32(const uint8_t* data, const size_t len)
{
    return crc32_reflected_generic(data, len, crc32_lookup_reflected_0x04C11DB7, 0xFFFFFFFF, true);
}
uint32_t crc32_bzip2(const uint8_t* data, const size_t len)
{
    return crc32_generic(data, len, crc32_lookup_0x04C11DB7, 0xFFFFFFFF, true);
}
uint32_t crc32_mpeg2(const uint8_t* data, const size_t len)
{
    return crc32_generic(data, len, crc32_lookup_0x04C11DB7, 0xFFFFFFFF, false);
}
uint32_t crc32_sata(const uint8_t* data, const size_t len)
{
    return crc32_generic(data, len, crc32_lookup_0x04C11DB7, 0x52325032, false);
}
uint32_t crc32_C(const uint8_t* data, const size_t len)
{
    return crc32_reflected_generic(data, len, crc32_C_lookup, 0xFFFFFFFF, true);
}
#endif  // DOXYGEN_SHOULD_SKIP_THIS