73 #ifdef CRCPP_USE_CPP11
75 #define crcpp_uint8 ::std::uint8_t
78 #define crcpp_uint8 uint8_t
83 #ifdef CRCPP_USE_CPP11
85 #define crcpp_uint16 ::std::uint16_t
88 #define crcpp_uint16 uint16_t
93 #ifdef CRCPP_USE_CPP11
95 #define crcpp_uint32 ::std::uint32_t
98 #define crcpp_uint32 uint32_t
103 #ifdef CRCPP_USE_CPP11
105 #define crcpp_uint64 ::std::uint64_t
108 #define crcpp_uint64 uint64_t
113 #ifdef CRCPP_USE_CPP11
115 #define crcpp_size ::std::size_t
118 #define crcpp_size size_t
122#ifdef CRCPP_USE_CPP11
124 #define crcpp_constexpr constexpr
127 #define crcpp_constexpr const
130#ifdef CRCPP_USE_NAMESPACE
144 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
150 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
165 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
170#ifdef CRCPP_USE_CPP11
176 const CRCType* GetTable()
const;
178 CRCType operator[](
unsigned char index)
const;
184 CRCType table[1 << CHAR_BIT];
189 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
192 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
193 static CRCType Calculate(
const void* data,
198 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
201 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
202 static CRCType Calculate(
const void* data,
209#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
220#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
237#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
245#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
254#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
264#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
269#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
275#ifdef CRCPP_USE_CPP11
277 CRC(
const CRC& other) =
delete;
278 CRC& operator=(
const CRC& other) =
delete;
279 CRC(
CRC&& other) =
delete;
280 CRC& operator=(
CRC&& other) =
delete;
284#ifndef CRCPP_USE_CPP11
287 CRC& operator=(
const CRC& other);
290 template <
typename IntegerType>
291 static IntegerType Reflect(IntegerType value,
crcpp_uint16 numBits);
293 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
294 static CRCType Finalize(CRCType remainder, CRCType finalXOR,
bool reflectOutput);
296 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
297 static CRCType UndoFinalize(CRCType remainder, CRCType finalXOR,
bool reflectOutput);
299 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
300 static CRCType CalculateRemainder(
const void* data,
305 template <
typename CRCType, crcpp_u
int16 CRCW
idth>
306 static CRCType CalculateRemainder(
const void* data,
311 template <
typename IntegerType>
312 static crcpp_constexpr IntegerType BoundedConstexprValue(IntegerType x);
323template <
typename CRCType, crcpp_u
int16 CRCW
idth>
335template <
typename CRCType, crcpp_u
int16 CRCW
idth>
340#ifdef CRCPP_USE_CPP11
347template <
typename CRCType, crcpp_u
int16 CRCW
idth>
349 : parameters(::std::move(parameters)) {
360template <
typename CRCType, crcpp_u
int16 CRCW
idth>
371template <
typename CRCType, crcpp_u
int16 CRCW
idth>
383template <
typename CRCType, crcpp_u
int16 CRCW
idth>
393template <
typename CRCType, crcpp_u
int16 CRCW
idth>
396 static crcpp_constexpr CRCType BIT_MASK((CRCType(1) << (CRCWidth - CRCType(1))) |
397 ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)));
399 static crcpp_constexpr CRCType SHIFT(CRC::BoundedConstexprValue(CHAR_BIT - CRCWidth));
402 unsigned char byte = 0;
406 crc = CRC::CalculateRemainder<CRCType, CRCWidth>(&
byte,
sizeof(
byte), parameters, CRCType(0));
413 if (!parameters.reflectInput && CRCWidth < CHAR_BIT) {
432template <
typename CRCType, crcpp_u
int16 CRCW
idth>
434 CRCType remainder = CalculateRemainder(data, size, parameters, parameters.
initialValue);
438 return Finalize<CRCType, CRCWidth>(remainder,
453template <
typename CRCType, crcpp_u
int16 CRCW
idth>
461 remainder = CalculateRemainder(data, size, parameters, remainder);
465 return Finalize<CRCType, CRCWidth>(remainder,
479template <
typename CRCType, crcpp_u
int16 CRCW
idth>
483 CRCType remainder = CalculateRemainder(data, size, lookupTable, parameters.
initialValue);
487 return Finalize<CRCType, CRCWidth>(remainder,
503template <
typename CRCType, crcpp_u
int16 CRCW
idth>
513 remainder = CalculateRemainder(data, size, lookupTable, remainder);
517 return Finalize<CRCType, CRCWidth>(remainder,
529template <
typename IntegerType>
530inline IntegerType CRC::Reflect(IntegerType value,
crcpp_uint16 numBits) {
531 IntegerType reversedValue(0);
534 reversedValue = (reversedValue << 1) | (value & 1);
538 return reversedValue;
550template <
typename CRCType, crcpp_u
int16 CRCW
idth>
551inline CRCType CRC::Finalize(CRCType remainder, CRCType finalXOR,
bool reflectOutput) {
554 (CRCType(1) << (CRCWidth - CRCType(1))) | ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1));
557 remainder = Reflect(remainder, CRCWidth);
560 return (remainder ^ finalXOR) & BIT_MASK;
580template <
typename CRCType, crcpp_u
int16 CRCW
idth>
581inline CRCType CRC::UndoFinalize(CRCType crc, CRCType finalXOR,
bool reflectOutput) {
584 (CRCType(1) << (CRCWidth - CRCType(1))) | ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1));
586 crc = (crc & BIT_MASK) ^ finalXOR;
589 crc = Reflect(crc, CRCWidth);
606template <
typename CRCType, crcpp_u
int16 CRCW
idth>
607inline CRCType CRC::CalculateRemainder(
const void* data,
609 const Parameters<CRCType, CRCWidth>& parameters,
611#ifdef CRCPP_USE_CPP11
614 static_assert(::std::numeric_limits<CRCType>::digits >= CRCWidth,
615 "CRCType is too small to contain a CRC of width CRCWidth.");
620 static_assert_failed_CRCType_is_too_small_to_contain_a_CRC_of_width_CRCWidth =
621 1 / (::std::numeric_limits<CRCType>::digits >= CRCWidth ? 1 : 0)
625 const unsigned char* current =
reinterpret_cast<const unsigned char*
>(data);
629 if (parameters.reflectInput) {
630 CRCType polynomial = CRC::Reflect(parameters.polynomial, CRCWidth);
632 remainder ^= *current++;
636#ifdef CRCPP_BRANCHLESS
642 remainder = (remainder >> 1) ^ ((remainder & 1) * polynomial);
644 remainder = (remainder & 1) ? ((remainder >> 1) ^ polynomial) : (remainder >> 1);
648 }
else if (CRCWidth >= CHAR_BIT) {
649 static crcpp_constexpr CRCType CRC_WIDTH_MINUS_ONE(CRCWidth - CRCType(1));
650#ifndef CRCPP_BRANCHLESS
651 static crcpp_constexpr CRCType CRC_HIGHEST_BIT_MASK(CRCType(1) << CRC_WIDTH_MINUS_ONE);
653 static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CRCWidth - CHAR_BIT));
656 remainder ^= (
static_cast<CRCType
>(*current++) << SHIFT);
660#ifdef CRCPP_BRANCHLESS
666 remainder = (remainder << 1) ^ (((remainder >> CRC_WIDTH_MINUS_ONE) & 1) * parameters.polynomial);
669 (remainder & CRC_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ parameters.polynomial) : (remainder << 1);
675#ifndef CRCPP_BRANCHLESS
676 static crcpp_constexpr CRCType CHAR_BIT_HIGHEST_BIT_MASK(CRCType(1) << CHAR_BIT_MINUS_ONE);
678 static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CHAR_BIT - CRCWidth));
680 CRCType polynomial = parameters.polynomial << SHIFT;
684 remainder ^= *current++;
688#ifdef CRCPP_BRANCHLESS
694 remainder = (remainder << 1) ^ (((remainder >> CHAR_BIT_MINUS_ONE) & 1) * polynomial);
697 (remainder & CHAR_BIT_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ polynomial) : (remainder << 1);
719template <
typename CRCType, crcpp_u
int16 CRCW
idth>
720inline CRCType CRC::CalculateRemainder(
const void* data,
722 const Table<CRCType, CRCWidth>& lookupTable,
724 const unsigned char* current =
reinterpret_cast<const unsigned char*
>(data);
726 if (lookupTable.GetParameters().reflectInput) {
728#if defined(WIN32) || defined(_WIN32) || defined(WINCE)
732 #pragma warning(push)
733 #pragma warning(disable : 4333)
735 remainder = (remainder >> CHAR_BIT) ^ lookupTable[
static_cast<unsigned char>(remainder ^ *current++)];
736#if defined(WIN32) || defined(_WIN32) || defined(WINCE)
740 }
else if (CRCWidth >= CHAR_BIT) {
741 static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CRCWidth - CHAR_BIT));
745 (remainder << CHAR_BIT) ^ lookupTable[static_cast<unsigned char>((remainder >> SHIFT) ^ *current++)];
748 static crcpp_constexpr CRCType SHIFT(BoundedConstexprValue(CHAR_BIT - CRCWidth));
754 remainder = lookupTable[
static_cast<unsigned char>(remainder ^ *current++)];
773template <
typename IntegerType>
774inline crcpp_constexpr IntegerType CRC::BoundedConstexprValue(IntegerType x) {
775 return (x < IntegerType(0)) ? IntegerType(0) : x;
778#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
792 static const Parameters<crcpp_uint8, 4> parameters = {0x3, 0x0, 0x0,
true,
true};
809 static const Parameters<crcpp_uint8, 5> parameters = {0x09, 0x09, 0x00,
false,
false};
826 static const Parameters<crcpp_uint8, 5> parameters = {0x15, 0x00, 0x00,
true,
true};
843 static const Parameters<crcpp_uint8, 5> parameters = {0x05, 0x1F, 0x1F,
true,
true};
860 static const Parameters<crcpp_uint8, 6> parameters = {0x27, 0x3F, 0x00,
false,
false};
877 static const Parameters<crcpp_uint8, 6> parameters = {0x07, 0x3F, 0x00,
false,
false};
894 static const Parameters<crcpp_uint8, 6> parameters = {0x03, 0x00, 0x00,
true,
true};
911 static const Parameters<crcpp_uint8, 7> parameters = {0x09, 0x00, 0x00,
false,
false};
933#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
947 static const Parameters<crcpp_uint8, 8> parameters = {0x1D, 0xFF, 0x00,
true,
true};
964 static const Parameters<crcpp_uint8, 8> parameters = {0x31, 0x00, 0x00,
true,
true};
981 static const Parameters<crcpp_uint8, 8> parameters = {0x9B, 0x00, 0x00,
true,
true};
998 static const Parameters<crcpp_uint16, 10> parameters = {0x233, 0x000, 0x000,
false,
false};
1015 static const Parameters<crcpp_uint16, 10> parameters = {0x3D9, 0x3FF, 0x000,
false,
false};
1032 static const Parameters<crcpp_uint16, 11> parameters = {0x385, 0x01A, 0x000,
false,
false};
1049 static const Parameters<crcpp_uint16, 12> parameters = {0xF13, 0xFFF, 0x000,
false,
false};
1066 static const Parameters<crcpp_uint16, 12> parameters = {0x80F, 0x000, 0x000,
false,
false};
1083 static const Parameters<crcpp_uint16, 12> parameters = {0x80F, 0x000, 0x000,
false,
true};
1100 static const Parameters<crcpp_uint16, 13> parameters = {0x1CF5, 0x0000, 0x0000,
false,
false};
1117 static const Parameters<crcpp_uint16, 15> parameters = {0x4599, 0x0000, 0x0000,
false,
false};
1134 static const Parameters<crcpp_uint16, 15> parameters = {0x6815, 0x0000, 0x0001,
false,
false};
1190#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
1204 static const Parameters<crcpp_uint16, 16> parameters = {0xC867, 0xFFFF, 0x0000,
false,
false};
1221 static const Parameters<crcpp_uint16, 16> parameters = {0x0589, 0x0000, 0x0001,
false,
false};
1238 static const Parameters<crcpp_uint16, 16> parameters = {0x0589, 0x0000, 0x0000,
false,
false};
1255 static const Parameters<crcpp_uint16, 16> parameters = {0x3D65, 0x0000, 0xFFFF,
true,
true};
1294#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
1308 static const Parameters<crcpp_uint16, 16> parameters = {0x8005, 0x0000, 0xFFFF,
true,
true};
1325 static const Parameters<crcpp_uint16, 16> parameters = {0x8005, 0xFFFF, 0x0000,
true,
true};
1342 static const Parameters<crcpp_uint16, 16> parameters = {0x8BB7, 0x0000, 0x0000,
false,
false};
1359 static const Parameters<crcpp_uint16, 16> parameters = {0x8005, 0xFFFF, 0xFFFF,
true,
true};
1376 static const Parameters<crcpp_uint16, 16> parameters = {0x8005, 0xFFFF, 0x0000,
false,
false};
1416#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
1430 static const Parameters<crcpp_uint32, 17> parameters = {0x1685B, 0x00000, 0x00000,
false,
false};
1447 static const Parameters<crcpp_uint32, 21> parameters = {0x102899, 0x000000, 0x000000,
false,
false};
1464 static const Parameters<crcpp_uint32, 24> parameters = {0x864CFB, 0xB704CE, 0x000000,
false,
false};
1481 static const Parameters<crcpp_uint32, 24> parameters = {0x5D6DCB, 0xFEDCBA, 0x000000,
false,
false};
1498 static const Parameters<crcpp_uint32, 24> parameters = {0x5D6DCB, 0xABCDEF, 0x000000,
false,
false};
1515 static const Parameters<crcpp_uint32, 30> parameters = {0x2030B9C7, 0x3FFFFFFF, 0x00000000,
false,
false};
1554#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
1568 static const Parameters<crcpp_uint32, 32> parameters = {0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF,
true,
true};
1607#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
1621 static const Parameters<crcpp_uint32, 32> parameters = {0x814141AB, 0x00000000, 0x00000000,
false,
false};
1638 static const Parameters<crcpp_uint64, 40> parameters = {0x0004820009, 0x0000000000, 0xFFFFFFFFFF,
false,
false};
1655 static const Parameters<crcpp_uint64, 64> parameters = {0x42F0E1EBA9EA3693,
1664#ifdef CRCPP_USE_NAMESPACE
#define crcpp_constexpr
Compile-time expression definition.
#define crcpp_uint16
Unsigned 16-bit integer definition, used primarily for parameter definitions.
#define crcpp_size
Unsigned size definition, used for specifying data sizes.
Static class for computing CRCs.
static const Parameters< crcpp_uint16, 16 > & CRC_16_XMODEM()
Returns a set of parameters for CRC-16 XMODEM (aka CRC-16 ZMODEM, CRC-16 ACORN, CRC-16 LTE).
static const Parameters< crcpp_uint8, 8 > & CRC_8()
Returns a set of parameters for CRC-8 SMBus.
static const Parameters< crcpp_uint32, 32 > & CRC_32_MPEG2()
Returns a set of parameters for CRC-32 MPEG-2.
static const Parameters< crcpp_uint16, 16 > & CRC_16_BUYPASS()
Returns a set of parameters for CRC-16 BUYPASS (aka CRC-16 VERIFONE, CRC-16 UMTS).
static const Parameters< crcpp_uint16, 16 > & CRC_16_KERMIT()
Returns a set of parameters for CRC-16 KERMIT (aka CRC-16 CCITT, CRC-16 CCITT-TRUE).
static const Parameters< crcpp_uint16, 16 > & CRC_16_GENIBUS()
Returns a set of parameters for CRC-16 GENIBUS (aka CRC-16 EPC, CRC-16 I-CODE, CRC-16 DARC).
static const Parameters< crcpp_uint32, 32 > & CRC_32_BZIP2()
Returns a set of parameters for CRC-32 BZIP2 (aka CRC-32 AAL5, CRC-32 DECT-B, CRC-32 B-CRC).
static const Parameters< crcpp_uint16, 16 > & CRC_16_CCITTFALSE()
Returns a set of parameters for CRC-16 CCITT FALSE.
static const Parameters< crcpp_uint32, 32 > & CRC_32_POSIX()
Returns a set of parameters for CRC-32 POSIX.
static const Parameters< crcpp_uint16, 16 > & CRC_16_X25()
Returns a set of parameters for CRC-16 X-25 (aka CRC-16 IBM-SDLC, CRC-16 ISO-HDLC,...
static CRCType Calculate(const void *data, crcpp_size size, const Parameters< CRCType, CRCWidth > ¶meters)
Computes a CRC.
static const Parameters< crcpp_uint16, 16 > & CRC_16_ARC()
Returns a set of parameters for CRC-16 ARC (aka CRC-16 IBM, CRC-16 LHA).
static const Parameters< crcpp_uint32, 32 > & CRC_32()
Returns a set of parameters for CRC-32 (aka CRC-32 ADCCP, CRC-32 PKZip).
Table< CRCType, CRCWidth > MakeTable() const
Returns a CRC lookup table construct using these CRC parameters.
CRCType initialValue
Initial CRC value.
CRCType polynomial
CRC polynomial.
CRCType finalXOR
Value to XOR with the final CRC.
bool reflectInput
true to reflect all input bytes
bool reflectOutput
true to reflect the output CRC (reflection occurs before the final XOR)
CRC lookup table. After construction, the CRC parameters are fixed.
const CRCType * GetTable() const
Gets the CRC table.
const Parameters< CRCType, CRCWidth > & GetParameters() const
Gets the CRC parameters used to construct the CRC table.
CRCType operator[](unsigned char index) const
Gets an entry in the CRC table.
Table(const Parameters< CRCType, CRCWidth > ¶meters)
Constructs a CRC table from a set of CRC parameters.