![]() |
|
|||
File indexing completed on 2025-07-09 08:28:41
0001 // Boost CRC library crc.hpp header file -----------------------------------// 0002 0003 // Copyright 2001, 2004, 2011 Daryle Walker. 0004 // Distributed under the Boost Software License, Version 1.0. (See the 0005 // accompanying file LICENSE_1_0.txt or a copy at 0006 // <http://www.boost.org/LICENSE_1_0.txt>.) 0007 0008 // See <http://www.boost.org/libs/crc/> for the library's home page. 0009 0010 /** \file 0011 \brief A collection of function templates and class templates that compute 0012 various forms of Cyclic Redundancy Codes (CRCs). 0013 0014 \author Daryle Walker 0015 0016 \version 1.5 0017 0018 \copyright Boost Software License, version 1.0 0019 0020 Contains the declarations (and definitions) of various kinds of CRC 0021 computation functions, function object types, and encapsulated policy types. 0022 0023 \warning The sample CRC-computer types were just checked against the 0024 <a href="http://regregex.bbcmicro.net/crc-catalogue.htm">Catalogue of 0025 parametrised CRC algorithms</a>. New type aliases were added where I got 0026 a standard wrong. However, the mistaken <code>typedef</code>s are still 0027 there for backwards compatibility. 0028 \note There are references to the <i>Rocksoft™ Model CRC 0029 Algorithm</i>, as described within \"A Painless Guide to CRC Error 0030 Detection Algorithms,\" linked from \"<a 0031 href="http://www.ross.net/crc/crcpaper.html">CRC: A Paper On CRCs</a>\" by 0032 Ross Williams. It will be abbreviated \"RMCA\" in other documentation 0033 blocks. 0034 */ 0035 0036 #ifndef BOOST_CRC_HPP 0037 #define BOOST_CRC_HPP 0038 0039 #include <array> // for std::array 0040 #include <climits> // for CHAR_BIT, etc. 0041 #include <cstddef> // for std::size_t 0042 #include <cstdint> // for UINTMAX_C, std::uintmax_t 0043 #include <limits> // for std::numeric_limits 0044 #include <type_traits> // for std::conditional, std::integral_constant 0045 0046 // Local reimplementation of boost::uint_t, to avoid dependency on Integer 0047 0048 namespace boost { 0049 namespace crc_detail { 0050 0051 struct uint_t_8 0052 { 0053 typedef std::uint_least8_t least; 0054 typedef std::uint_fast8_t fast; 0055 }; 0056 0057 struct uint_t_16 0058 { 0059 typedef std::uint_least16_t least; 0060 typedef std::uint_fast16_t fast; 0061 }; 0062 0063 struct uint_t_32 0064 { 0065 typedef std::uint_least32_t least; 0066 typedef std::uint_fast32_t fast; 0067 }; 0068 0069 struct uint_t_64 0070 { 0071 typedef std::uint_least64_t least; 0072 typedef std::uint_fast64_t fast; 0073 }; 0074 0075 struct uint_t_none 0076 { 0077 }; 0078 0079 template<int Bits> struct uint_t: 0080 std::conditional< (Bits <= 8), uint_t_8, 0081 typename std::conditional< (Bits <= 16), uint_t_16, 0082 typename std::conditional< (Bits <= 32), uint_t_32, 0083 typename std::conditional< (Bits <= 64), uint_t_64, 0084 uint_t_none>::type>::type>::type>::type 0085 { 0086 }; 0087 0088 } // namespace crc_detail 0089 } // namespace boost 0090 0091 // The type of CRC parameters that can go in a template should be related 0092 // on the CRC's bit count. This macro expresses that type in a compact 0093 // form. 0094 #define BOOST_CRC_PARM_TYPE typename ::boost::crc_detail::uint_t<Bits>::fast 0095 0096 namespace boost 0097 { 0098 0099 0100 // Forward declarations ----------------------------------------------------// 0101 0102 //! Bit-wise CRC computer 0103 template < std::size_t Bits > 0104 class crc_basic; 0105 0106 //! Table-driven CRC computer, usable as a function object 0107 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u, 0108 BOOST_CRC_PARM_TYPE InitRem = 0u, 0109 BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false, 0110 bool ReflectRem = false > 0111 class crc_optimal; 0112 0113 //! Compute the (unaugmented) CRC of a memory block 0114 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 0115 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 0116 bool ReflectIn, bool ReflectRem > 0117 typename crc_detail::uint_t<Bits>::fast crc( void const *buffer, 0118 std::size_t byte_count); 0119 0120 //! Compute the CRC of a memory block, with any augmentation provided by user 0121 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > 0122 typename crc_detail::uint_t<Bits>::fast augmented_crc( void const *buffer, 0123 std::size_t byte_count, 0124 typename crc_detail::uint_t<Bits>::fast initial_remainder = 0u); 0125 0126 //! Computation type for ARC|CRC-16|CRC-IBM|CRC-16/ARC|CRC-16/LHA standard 0127 typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type; 0128 //! Computation type for CRC-16/CCITT-FALSE standard 0129 typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_false_t; 0130 //! Computation type for the CRC mistakenly called the CCITT standard 0131 typedef crc_ccitt_false_t crc_ccitt_type; 0132 //! Computation type for the actual 0133 //! KERMIT|CRC-16/CCITT|CRC-16/CCITT-TRUE|CRC-CCITT standard 0134 typedef crc_optimal<16, 0x1021, 0, 0, true, true> crc_ccitt_true_t; 0135 //! Computation type that I mistakenly called the XMODEM standard; it inverts 0136 //! both reflection parameters and reflects the truncated divisor (Don't use?!) 0137 typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type; 0138 //! Computation type for the actual XMODEM|ZMODEM|CRC-16/ACORN standard 0139 typedef crc_optimal<16, 0x1021, 0, 0, false, false> crc_xmodem_t; 0140 0141 //! Computation type for CRC-32|CRC-32/ADCCP|PKZIP standard 0142 typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> 0143 crc_32_type; 0144 0145 0146 // Forward declarations for implementation detail stuff --------------------// 0147 // (Just for the stuff that will be needed for the next two sections) 0148 0149 //! \cond 0150 namespace detail 0151 { 0152 //! Mix-in class to add a possibly-reflecting member function 0153 template < int BitLength, bool DoIt, int Id = 0 > 0154 class possible_reflector; 0155 0156 //! Mix-in class for byte-fed, table-driven CRC algorithms 0157 template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect, 0158 int Id = 0 > 0159 class crc_driver; 0160 0161 } // namespace detail 0162 //! \endcond 0163 0164 0165 // Simple cyclic redundancy code (CRC) class declaration -------------------// 0166 0167 /** Objects of this type compute the CRC checksum of submitted data, where said 0168 data can be entered piecemeal through several different kinds of groupings. 0169 Modulo-2 polynomial division steps are always performed bit-wise, without 0170 the use of pre-computation tables. Said division uses the altered 0171 algorithm, so any data has to be unaugmented. 0172 0173 \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits 0174 0175 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 0176 the RMCA) 0177 */ 0178 template < std::size_t Bits > 0179 class crc_basic 0180 { 0181 public: 0182 // Type 0183 /** \brief The register type used for computations 0184 0185 This type is used for CRC calculations and is the type for any returned 0186 checksums and returned or submitted remainders, (truncated) divisors, or 0187 XOR masks. It is a built-in unsigned integer type. 0188 */ 0189 typedef typename boost::crc_detail::uint_t<Bits>::fast value_type; 0190 0191 // Constant for the template parameter 0192 //! A copy of \a Bits provided for meta-programming purposes 0193 static const std::size_t bit_count = Bits; 0194 0195 // Constructor (use the automatic copy-ctr, move-ctr, and dtr) 0196 //! Create a computer, separately listing each needed parameter 0197 explicit crc_basic( value_type truncated_polynomial, 0198 value_type initial_remainder = 0, value_type final_xor_value = 0, 0199 bool reflect_input = false, bool reflect_remainder = false ); 0200 0201 // Internal Operations 0202 //! Return the (truncated) polynomial divisor 0203 value_type get_truncated_polynominal() const; 0204 //! Return what the polynomial remainder was set to during construction 0205 value_type get_initial_remainder() const; 0206 //! Return the XOR-mask used during output processing 0207 value_type get_final_xor_value() const; 0208 //! Check if input-bytes will be reflected before processing 0209 bool get_reflect_input() const; 0210 //! Check if the remainder will be reflected during output processing 0211 bool get_reflect_remainder() const; 0212 0213 //! Return the remainder based from already-processed bits 0214 value_type get_interim_remainder() const; 0215 //! Change the interim remainder to a new value 0216 void reset( value_type new_rem ); 0217 //! Change the interim remainder back to the initial value 0218 void reset(); 0219 0220 // External Operations 0221 //! Submit a single bit for input processing 0222 void process_bit( bool bit ); 0223 //! Submit the lowest \a bit_length bits of a byte for input processing 0224 void process_bits( unsigned char bits, std::size_t bit_length ); 0225 //! Submit a single byte for input processing 0226 void process_byte( unsigned char byte ); 0227 //! Submit a memory block for input processing, iterator-pair style 0228 void process_block( void const *bytes_begin, void const *bytes_end ); 0229 //! Submit a memory block for input processing, pointer-and-size style 0230 void process_bytes( void const *buffer, std::size_t byte_count ); 0231 0232 //! Return the checksum of the already-processed bits 0233 value_type checksum() const; 0234 0235 private: 0236 // Member data 0237 value_type rem_; 0238 value_type poly_, init_, final_; // non-const to allow assignability 0239 bool rft_in_, rft_out_; // non-const to allow assignability 0240 0241 }; // boost::crc_basic 0242 0243 0244 // Optimized cyclic redundancy code (CRC) class declaration ----------------// 0245 0246 /** Objects of this type compute the CRC checksum of submitted data, where said 0247 data can be entered piecemeal through several different kinds of groupings. 0248 Modulo-2 polynomial division steps are performed byte-wise, aided by the use 0249 of pre-computation tables. Said division uses the altered algorithm, so any 0250 data has to be unaugmented. 0251 0252 \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits 0253 0254 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 0255 the RMCA) 0256 \tparam TruncPoly The lowest coefficients of the divisor polynomial. The 0257 highest-order coefficient is omitted and always assumed to be 1. Defaults 0258 to \c 0, i.e. the only non-zero term is the implicit one for 0259 x<sup><var>Bits</var></sup>. (\e Poly from the RMCA) 0260 \tparam InitRem The (unaugmented) initial state of the polynomial 0261 remainder. Defaults to \c 0 if omitted. (\e Init from the RMCA) 0262 \tparam FinalXor The (XOR) bit-mask to be applied to the output remainder, 0263 after possible reflection but before returning. Defaults to \c 0 (i.e. no 0264 bit changes) if omitted. (\e XorOut from the RMCA) 0265 \tparam ReflectIn If \c true, input bytes are read lowest-order bit first, 0266 otherwise highest-order bit first. Defaults to \c false if omitted. 0267 (\e RefIn from the RMCA) 0268 \tparam ReflectRem If \c true, the output remainder is reflected before the 0269 XOR-mask. Defaults to \c false if omitted. (\e RefOut from the RMCA) 0270 0271 \todo Get rid of the default value for \a TruncPoly. Choosing a divisor is 0272 an important decision with many factors, so a default is never useful, 0273 especially a bad one. 0274 */ 0275 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 0276 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 0277 bool ReflectIn, bool ReflectRem > 0278 class crc_optimal 0279 { 0280 public: 0281 // Type 0282 //! \copydoc boost::crc_basic::value_type 0283 typedef typename boost::crc_detail::uint_t<Bits>::fast value_type; 0284 0285 // Constants for the template parameters 0286 //! \copydoc boost::crc_basic::bit_count 0287 static const std::size_t bit_count = Bits; 0288 //! A copy of \a TruncPoly provided for meta-programming purposes 0289 static const value_type truncated_polynominal = TruncPoly; 0290 //! A copy of \a InitRem provided for meta-programming purposes 0291 static const value_type initial_remainder = InitRem; 0292 //! A copy of \a FinalXor provided for meta-programming purposes 0293 static const value_type final_xor_value = FinalXor; 0294 //! A copy of \a ReflectIn provided for meta-programming purposes 0295 static const bool reflect_input = ReflectIn; 0296 //! A copy of \a ReflectRem provided for meta-programming purposes 0297 static const bool reflect_remainder = ReflectRem; 0298 0299 // Constructor (use the automatic copy-ctr, move-ctr, and dtr) 0300 //! Create a computer, giving an initial remainder if desired 0301 explicit crc_optimal( value_type init_rem = initial_remainder ); 0302 0303 // Internal Operations 0304 //! \copybrief boost::crc_basic::get_truncated_polynominal 0305 value_type get_truncated_polynominal() const; 0306 //! \copybrief boost::crc_basic::get_initial_remainder 0307 value_type get_initial_remainder() const; 0308 //! \copybrief boost::crc_basic::get_final_xor_value 0309 value_type get_final_xor_value() const; 0310 //! \copybrief boost::crc_basic::get_reflect_input 0311 bool get_reflect_input() const; 0312 //! \copybrief boost::crc_basic::get_reflect_remainder 0313 bool get_reflect_remainder() const; 0314 0315 //! \copybrief boost::crc_basic::get_interim_remainder 0316 value_type get_interim_remainder() const; 0317 //! Change the interim remainder to either a given value or the initial one 0318 void reset( value_type new_rem = initial_remainder ); 0319 0320 // External Operations 0321 //! \copybrief boost::crc_basic::process_byte 0322 void process_byte( unsigned char byte ); 0323 //! \copybrief boost::crc_basic::process_block 0324 void process_block( void const *bytes_begin, void const *bytes_end ); 0325 //! \copybrief boost::crc_basic::process_bytes 0326 void process_bytes( void const *buffer, std::size_t byte_count ); 0327 0328 //! \copybrief boost::crc_basic::checksum 0329 value_type checksum() const; 0330 0331 // Operators 0332 //! Submit a single byte for input processing, suitable for the STL 0333 void operator ()( unsigned char byte ); 0334 //! Return the checksum of the already-processed bits, suitable for the STL 0335 value_type operator ()() const; 0336 0337 private: 0338 // Implementation types 0339 // (Processing for reflected input gives reflected remainders, so you only 0340 // have to apply output-reflection if Reflect-Remainder doesn't match 0341 // Reflect-Input.) 0342 typedef detail::possible_reflector<Bits, ReflectIn> reflect_i_type; 0343 typedef detail::crc_driver<Bits, TruncPoly, ReflectIn> crc_table_type; 0344 typedef detail::possible_reflector<Bits, ReflectRem != ReflectIn> 0345 reflect_o_type; 0346 0347 // Member data 0348 value_type rem_; 0349 0350 }; // boost::crc_optimal 0351 0352 0353 // Implementation detail stuff ---------------------------------------------// 0354 0355 //! \cond 0356 namespace detail 0357 { 0358 /** \brief Meta-programming integral constant for a single-bit bit-mask 0359 0360 Generates a compile-time constant for a bit-mask that affects a single 0361 bit. The \c value will be 2<sup><var>BitIndex</var></sup>. The \c type 0362 will be the smallest built-in unsigned integer type that can contain the 0363 value, unless there's a built-in type that the system can handle easier, 0364 then the \c type will be smallest fast-handled unsigned integer type. 0365 0366 \pre 0 \<= BitIndex \< \c std\::numeric_limits\<uintmax_t\>\::digits 0367 0368 \tparam BitIndex The place of the sole set bit. 0369 */ 0370 template < int BitIndex > 0371 struct high_bit_mask_c 0372 : std::integral_constant<typename boost::crc_detail::uint_t< BitIndex + 1 >::fast, 0373 ( UINTMAX_C(1) << BitIndex )> 0374 {}; 0375 0376 /** \brief Meta-programming integral constant for a lowest-bits bit-mask 0377 0378 Generates a compile-time constant for a bit-mask that affects the lowest 0379 bits. The \c value will be 2<sup><var>BitCount</var></sup> - 1. The 0380 \c type will be the smallest built-in unsigned integer type that can 0381 contain the value, unless there's a built-in type that the system can 0382 handle easier, then the \c type will be smallest fast-handled unsigned 0383 integer type. 0384 0385 \pre 0 \<= BitCount \<= \c std\::numeric_limits\<uintmax_t\>\::digits 0386 0387 \tparam BitCount The number of lowest-placed bits set. 0388 */ 0389 template < int BitCount > 0390 struct low_bits_mask_c 0391 : std::integral_constant<typename boost::crc_detail::uint_t< BitCount >::fast, ( 0392 BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1) ) - 1u) << 1 ) | 0393 UINTMAX_C( 1 )) : 0u )> 0394 {}; 0395 0396 /** \brief Reflects the bits of a number 0397 0398 Reverses the order of the given number of bits within a value. For 0399 instance, if the given reflect count is 5, then the bit values for the 0400 16- and 1-place will switch and the 8- and 2-place will switch, leaving 0401 the other bits alone. (The 4-place bit is in the middle, so it wouldn't 0402 change.) 0403 0404 \pre \a Unsigned is a built-in unsigned integer type 0405 \pre 0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits 0406 0407 \tparam Unsigned The type of \a x. 0408 0409 \param x The value to be (partially) reflected. 0410 \param word_length The number of low-order bits to reflect. Defaults 0411 to the total number of value bits in \a Unsigned. 0412 0413 \return The (partially) reflected value. 0414 0415 \todo Check if this is the fastest way. 0416 */ 0417 template < typename Unsigned > 0418 Unsigned reflect_unsigned( Unsigned x, int word_length 0419 = std::numeric_limits<Unsigned>::digits ) 0420 { 0421 for ( Unsigned l = 1u, h = static_cast<Unsigned>(l << (word_length - 1)) ; h > l ; h >>= 1, l 0422 <<= 1 ) 0423 { 0424 Unsigned const m = h | l, t = x & m; 0425 0426 if ( (t == h) || (t == l) ) 0427 x ^= m; 0428 } 0429 0430 return x; 0431 } 0432 0433 /** \brief Make a byte-to-byte-reflection map 0434 0435 Creates a mapping array so the results can be cached. Uses 0436 #reflect_unsigned to generate the element values. 0437 0438 \return An array <var>a</var> such that, for a given byte value 0439 <var>i</var>, <code><var>a</var>[ <var>i</var> ]</code> resolves to 0440 the reflected value of <var>i</var>. 0441 */ 0442 std::array< unsigned char, (UINTMAX_C( 1 ) << CHAR_BIT) > 0443 inline make_byte_reflection_table() 0444 { 0445 std::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> result; 0446 unsigned char i = 0u; 0447 0448 do 0449 result[ i ] = reflect_unsigned( i ); 0450 while ( ++i ); 0451 return result; 0452 } 0453 0454 /** \brief Reflects the bits of a single byte 0455 0456 Reverses the order of all the bits within a value. For instance, the 0457 bit values for the 2<sup><code>CHAR_BIT</code> - 1</sup>- and 1-place 0458 will switch and the 2<sup><code>CHAR_BIT</code> - 2</sup>- and 2-place 0459 will switch, etc. 0460 0461 \param x The byte value to be reflected. 0462 0463 \return The reflected value. 0464 0465 \note Since this could be the most common type of reflection, and the 0466 number of states is relatively small, the implementation pre-computes 0467 and uses a table of all the results. 0468 */ 0469 inline unsigned char reflect_byte( unsigned char x ) 0470 { 0471 static std::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> const 0472 table = make_byte_reflection_table(); 0473 0474 return table[ x ]; 0475 } 0476 0477 /** \brief Reflects some bits within a single byte 0478 0479 Like #reflect_unsigned, except it takes advantage of any (long-term) 0480 speed gains #reflect_byte may bring. 0481 0482 \pre 0 \< \a word_length \<= \c CHAR_BIT 0483 0484 \param x The value to be (partially) reflected. 0485 \param word_length The number of low-order bits to reflect. 0486 0487 \return The (partially) reflected value. 0488 */ 0489 inline unsigned char reflect_sub_byte( unsigned char x, int word_length ) 0490 { return reflect_byte(x) >> (CHAR_BIT - word_length); } 0491 0492 /** \brief Possibly reflects the bits of a number 0493 0494 Reverses the order of the given number of bits within a value. For 0495 instance, if the given reflect count is 5, then the bit values for the 0496 16- and 1-place will switch and the 8- and 2-place will switch, leaving 0497 the other bits alone. (The 4-place bit is in the middle, so it wouldn't 0498 change.) This variant function allows the reflection be controlled by 0499 an extra parameter, in case the decision to use reflection is made at 0500 run-time. 0501 0502 \pre \a Unsigned is a built-in unsigned integer type 0503 \pre 0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits 0504 0505 \tparam Unsigned The type of \a x. 0506 0507 \param x The value to be (partially) reflected. 0508 \param reflect Controls whether \a x is actually reflected (\c true) or 0509 left alone (\c false). 0510 \param word_length The number of low-order bits to reflect. Defaults 0511 to the total number of value bits in \a Unsigned. 0512 0513 \return The possibly (partially) reflected value. 0514 */ 0515 template < typename Unsigned > 0516 inline 0517 Unsigned reflect_optionally( Unsigned x, bool reflect, int word_length 0518 = std::numeric_limits<Unsigned>::digits ) 0519 { return reflect ? reflect_unsigned(x, word_length) : x; } 0520 0521 /** \brief Possibly reflects the bits of a single byte 0522 0523 Uses #reflect_byte (if \a reflect is \c true). 0524 0525 \param x The byte value to be (possibly) reflected. 0526 \param reflect Whether (\c true) or not (\c false) \a x is reflected. 0527 0528 \return <code><var>reflect</var> ? reflect_byte(<var>x</var>) : 0529 <var>x</var></code> 0530 */ 0531 inline 0532 unsigned char reflect_byte_optionally( unsigned char x, bool reflect ) 0533 { return reflect ? reflect_byte(x) : x; } 0534 0535 /** \brief Update a CRC remainder by several bits, assuming a non-augmented 0536 message 0537 0538 Performs several steps of division required by the CRC algorithm, giving 0539 a new remainder polynomial based on the divisor polynomial and the 0540 synthesized dividend polynomial (from the old remainder and the 0541 newly-provided input). The computations assume that the CRC is directly 0542 exposed from the remainder, without any zero-valued bits augmented to 0543 the message bits. 0544 0545 \pre \a Register and \a Word are both built-in unsigned integer types 0546 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0547 \::digits 0548 \pre 0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits 0549 0550 \tparam Register The type used for representing the remainder and 0551 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0552 is used as the coefficient of <i>x<sup>i</sup></i>. 0553 \tparam Word The type used for storing the incoming terms of the 0554 dividend modulo-2 polynomial. The bit at <code>2<sup>i</sup></code> 0555 is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is 0556 \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 - 0557 i</sup></i> otherwise. 0558 0559 \param[in] register_length The number of significant low-order bits 0560 to be used from \a Register values. It is the order of the modulo-2 0561 polynomial remainder and one less than the divisor's order. 0562 \param[in,out] remainder The upper part of the dividend polynomial 0563 before division, and the remainder polynomial after. 0564 \param[in] new_dividend_bits The coefficients for the next 0565 \a word_length lowest terms of the dividend polynomial. 0566 \param[in] truncated_divisor The lowest coefficients of the divisor 0567 polynomial. The highest-order coefficient is omitted and always 0568 assumed to be 1. 0569 \param[in] word_length The number of lowest-order bits to read from 0570 \a new_dividend_bits. 0571 \param[in] reflect If \c false, read from the highest-order marked 0572 bit from \a new_dividend_bits and go down, as normal. Otherwise, 0573 proceed from the lowest-order bit and go up. 0574 0575 \note This routine performs a modulo-2 polynomial division variant. 0576 The exclusive-or operations are applied in a different order, since 0577 that kind of operation is commutative and associative. It also 0578 assumes that the zero-valued augment string was applied before this 0579 step, which means that the updated remainder can be directly used as 0580 the final CRC. 0581 */ 0582 template < typename Register, typename Word > 0583 void crc_modulo_word_update( int register_length, Register &remainder, Word 0584 new_dividend_bits, Register truncated_divisor, int word_length, bool 0585 reflect ) 0586 { 0587 // Create this masking constant outside the loop. 0588 Register const high_bit_mask = UINTMAX_C(1) << (register_length - 1); 0589 0590 // The natural reading order for division is highest digit/bit first. 0591 // The "reflect" parameter switches this. However, building a bit mask 0592 // for the lowest bit is the easiest.... 0593 new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect, 0594 word_length ); 0595 0596 // Perform modulo-2 division for each new dividend input bit 0597 for ( int i = word_length ; i ; --i, new_dividend_bits >>= 1 ) 0598 { 0599 // compare the new bit with the remainder's highest 0600 remainder ^= ( new_dividend_bits & 1u ) ? high_bit_mask : 0u; 0601 0602 // perform modulo-2 division 0603 bool const quotient = (remainder & high_bit_mask) != 0; 0604 0605 remainder <<= 1; 0606 remainder ^= quotient ? truncated_divisor : 0u; 0607 0608 // The quotient isn't used for anything, so don't keep it. 0609 } 0610 0611 // Clear overflowed bits 0612 remainder &= (std::numeric_limits<Register>::max)() >> (std::numeric_limits<Register>::digits - register_length); 0613 } 0614 0615 /** \brief Update a CRC remainder by a single bit, assuming a non-augmented 0616 message 0617 0618 Performs the next step of division required by the CRC algorithm, giving 0619 a new remainder polynomial based on the divisor polynomial and the 0620 synthesized dividend polynomial (from the old remainder and the 0621 newly-provided input). The computations assume that the CRC is directly 0622 exposed from the remainder, without any zero-valued bits augmented to 0623 the message bits. 0624 0625 \pre \a Register is a built-in unsigned integer type 0626 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0627 \::digits 0628 0629 \tparam Register The type used for representing the remainder and 0630 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0631 is used as the coefficient of <i>x<sup>i</sup></i>. 0632 0633 \param[in] register_length The number of significant low-order bits 0634 to be used from \a Register values. It is the order of the modulo-2 0635 polynomial remainder and one less than the divisor's order. 0636 \param[in,out] remainder The upper part of the dividend polynomial 0637 before division, and the remainder polynomial after. 0638 \param[in] new_dividend_bit The coefficient for the constant term 0639 of the dividend polynomial. 0640 \param[in] truncated_divisor The lowest coefficients of the divisor 0641 polynomial. The highest-order coefficient is omitted and always 0642 assumed to be 1. 0643 0644 \note This routine performs a modulo-2 polynomial division variant. 0645 The exclusive-or operations are applied in a different order, since 0646 that kind of operation is commutative and associative. It also 0647 assumes that the zero-valued augment string was applied before this 0648 step, which means that the updated remainder can be directly used as 0649 the final CRC. 0650 */ 0651 template < typename Register > 0652 inline void crc_modulo_update( int register_length, Register &remainder, 0653 bool new_dividend_bit, Register truncated_divisor ) 0654 { 0655 crc_modulo_word_update( register_length, remainder, 0656 static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false ); 0657 } 0658 0659 /** \brief Update a CRC remainder by several bits, assuming an augmented 0660 message 0661 0662 Performs several steps of division required by the CRC algorithm, giving 0663 a new remainder polynomial based on the divisor polynomial and the 0664 synthesized dividend polynomial (from the old remainder and the 0665 newly-provided input). The computations assume that a zero-valued 0666 string of bits will be appended to the message before extracting the 0667 CRC. 0668 0669 \pre \a Register and \a Word are both built-in unsigned integer types 0670 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0671 \::digits 0672 \pre 0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits 0673 0674 \tparam Register The type used for representing the remainder and 0675 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0676 is used as the coefficient of <i>x<sup>i</sup></i>. 0677 \tparam Word The type used for storing the incoming terms of the 0678 dividend modulo-2 polynomial. The bit at <code>2<sup>i</sup></code> 0679 is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is 0680 \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 - 0681 i</sup></i> otherwise. 0682 0683 \param[in] register_length The number of significant low-order bits 0684 to be used from \a Register values. It is the order of the modulo-2 0685 polynomial remainder and one less than the divisor's order. 0686 \param[in,out] remainder The upper part of the dividend polynomial 0687 before division, and the remainder polynomial after. 0688 \param[in] new_dividend_bits The coefficients for the next 0689 \a word_length lowest terms of the dividend polynomial. 0690 \param[in] truncated_divisor The lowest coefficients of the divisor 0691 polynomial. The highest-order coefficient is omitted and always 0692 assumed to be 1. 0693 \param[in] word_length The number of lowest-order bits to read from 0694 \a new_dividend_bits. 0695 \param[in] reflect If \c false, read from the highest-order marked 0696 bit from \a new_dividend_bits and go down, as normal. Otherwise, 0697 proceed from the lowest-order bit and go up. 0698 0699 \note This routine performs straight-forward modulo-2 polynomial 0700 division. It assumes that an augment string will be processed at the 0701 end of the message bits before doing CRC analysis. 0702 \todo Use this function somewhere so I can test it. 0703 */ 0704 template < typename Register, typename Word > 0705 void augmented_crc_modulo_word_update( int register_length, Register 0706 &remainder, Word new_dividend_bits, Register truncated_divisor, int 0707 word_length, bool reflect ) 0708 { 0709 // Create this masking constant outside the loop. 0710 Register const high_bit_mask = UINTMAX_C(1) << (register_length - 1); 0711 0712 // The natural reading order for division is highest digit/bit first. 0713 // The "reflect" parameter switches this. However, building a bit mask 0714 // for the lowest bit is the easiest.... 0715 new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect, 0716 word_length ); 0717 0718 // Perform modulo-2 division for each new dividend input bit 0719 for ( int i = word_length ; i ; --i, new_dividend_bits >>= 1 ) 0720 { 0721 bool const quotient = (remainder & high_bit_mask) != 0; 0722 0723 remainder <<= 1; 0724 remainder |= new_dividend_bits & 1u; 0725 remainder ^= quotient ? truncated_divisor : 0u; 0726 0727 // The quotient isn't used for anything, so don't keep it. 0728 } 0729 } 0730 0731 /** \brief Update a CRC remainder by a single bit, assuming an augmented 0732 message 0733 0734 Performs the next step of division required by the CRC algorithm, giving 0735 a new remainder polynomial based on the divisor polynomial and the 0736 synthesized dividend polynomial (from the old remainder and the 0737 newly-provided input). The computations assume that a zero-valued 0738 string of bits will be appended to the message before extracting the 0739 CRC. 0740 0741 \pre \a Register is a built-in unsigned integer type 0742 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0743 \::digits 0744 0745 \tparam Register The type used for representing the remainder and 0746 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0747 is used as the coefficient of <i>x<sup>i</sup></i>. 0748 0749 \param[in] register_length The number of significant low-order bits 0750 to be used from \a Register values. It is the order of the modulo-2 0751 polynomial remainder and one less than the divisor's order. 0752 \param[in,out] remainder The upper part of the dividend polynomial 0753 before division, and the remainder polynomial after. 0754 \param[in] new_dividend_bit The coefficient for the constant term 0755 of the dividend polynomial. 0756 \param[in] truncated_divisor The lowest coefficients of the divisor 0757 polynomial. The highest-order coefficient is omitted and always 0758 assumed to be 1. 0759 0760 \note This routine performs straight-forward modulo-2 polynomial 0761 division. It assumes that an augment string will be processed at the 0762 end of the message bits before doing CRC analysis. 0763 \todo Use this function somewhere so I can test it. 0764 */ 0765 template < typename Register > 0766 inline void augmented_crc_modulo_update( int register_length, Register 0767 &remainder, bool new_dividend_bit, Register truncated_divisor ) 0768 { 0769 augmented_crc_modulo_word_update( register_length, remainder, 0770 static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false ); 0771 } 0772 0773 /** \brief A mix-in class that returns its argument 0774 0775 This class template makes a function object that returns its argument 0776 as-is. It's one case for #possible_reflector. 0777 0778 \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\> 0779 \::digits 0780 0781 \tparam BitLength How many significant bits arguments have. 0782 */ 0783 template < int BitLength > 0784 class non_reflector 0785 { 0786 public: 0787 /** \brief The type to check for specialization 0788 0789 This is a Boost integral constant indicating that this class 0790 does not reflect its input values. 0791 */ 0792 typedef std::false_type is_reflecting_type; 0793 /** \brief The type to check for register bit length 0794 0795 This is a Boost integral constant indicating how many 0796 significant bits won't actually be reflected. 0797 */ 0798 typedef std::integral_constant< int, BitLength > width_c; 0799 /** \brief The type of (not-)reflected values 0800 0801 This type is the input and output type for the (possible-) 0802 reflection function, which does nothing here. 0803 */ 0804 typedef typename boost::crc_detail::uint_t< BitLength >::fast value_type; 0805 0806 /** \brief Does nothing 0807 0808 Returns the given value, not reflecting any part of it. 0809 0810 \param x The value to not be reflected. 0811 0812 \return \a x 0813 */ 0814 inline static value_type reflect_q( value_type x ) 0815 { return x; } 0816 }; 0817 0818 /** \brief A mix-in class that reflects (the lower part of) its argument, 0819 generally for types larger than a byte 0820 0821 This class template makes a function object that returns its argument 0822 after reflecting its lower-order bits. It's one sub-case for 0823 #possible_reflector. 0824 0825 \pre \c CHAR_BIT \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t 0826 \>\::digits 0827 0828 \tparam BitLength How many significant bits arguments have. 0829 */ 0830 template < int BitLength > 0831 class super_byte_reflector 0832 { 0833 public: 0834 /** \brief The type to check for specialization 0835 0836 This is a Boost integral constant indicating that this class 0837 does reflect its input values. 0838 */ 0839 typedef std::true_type is_reflecting_type; 0840 /** \brief The type to check for register bit length 0841 0842 This is a Boost integral constant indicating how many 0843 significant bits will be reflected. 0844 */ 0845 typedef std::integral_constant< int, BitLength > width_c; 0846 /** \brief The type of reflected values 0847 0848 This is both the input and output type for the reflection function. 0849 */ 0850 typedef typename boost::crc_detail::uint_t< BitLength >::fast value_type; 0851 0852 /** \brief Reflect (part of) the given value 0853 0854 Reverses the order of the given number of bits within a value, 0855 using #reflect_unsigned. 0856 0857 \param x The value to be (partially) reflected. 0858 0859 \return ( <var>x</var> & 0860 ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT( 0861 <var>x</var> & (2<sup><var>width_c</var>\::value</sup> - 0862 1) ) 0863 */ 0864 inline static value_type reflect_q( value_type x ) 0865 { return reflect_unsigned(x, width_c::value); } 0866 }; 0867 0868 /** \brief A mix-in class that reflects (the lower part of) its argument, 0869 generally for bytes 0870 0871 This class template makes a function object that returns its argument 0872 after reflecting its lower-order bits. It's one sub-case for 0873 #possible_reflector. 0874 0875 \pre 0 \< \a BitLength \<= \c CHAR_BIT 0876 0877 \tparam BitLength How many significant bits arguments have. 0878 */ 0879 template < int BitLength > 0880 class sub_type_reflector 0881 { 0882 public: 0883 /** \brief The type to check for specialization 0884 0885 This is a Boost integral constant indicating that this class 0886 does reflect its input values. 0887 */ 0888 typedef std::true_type is_reflecting_type; 0889 /** \brief The type to check for register bit length 0890 0891 This is a Boost integral constant indicating how many 0892 significant bits will be reflected. 0893 */ 0894 typedef std::integral_constant< int, BitLength > width_c; 0895 /** \brief The type of reflected values 0896 0897 This is both the input and output type for the reflection function. 0898 */ 0899 typedef unsigned char value_type; 0900 0901 /** \brief Reflect (part of) the given value 0902 0903 Reverses the order of the given number of bits within a value, 0904 using #reflect_sub_byte. 0905 0906 \param x The value to be (partially) reflected. 0907 0908 \return ( <var>x</var> & 0909 ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT( 0910 <var>x</var> & (2<sup><var>width_c</var>\::value</sup> - 0911 1) ) 0912 */ 0913 inline static value_type reflect_q( value_type x ) 0914 { return reflect_sub_byte(x, width_c::value); } 0915 }; 0916 0917 /** \brief A mix-in class that reflects (the lower part of) its argument 0918 0919 This class template makes a function object that returns its argument 0920 after reflecting its lower-order bits. It's one case for 0921 #possible_reflector. 0922 0923 \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\> 0924 \::digits 0925 0926 \tparam BitLength How many significant bits arguments have. 0927 */ 0928 template < int BitLength > 0929 class reflector 0930 : public std::conditional< (BitLength > CHAR_BIT), 0931 super_byte_reflector<BitLength>, sub_type_reflector<BitLength> >::type 0932 { }; 0933 0934 /** This class template adds a member function #reflect_q that will 0935 conditionally reflect its first argument, controlled by a compile-time 0936 parameter. 0937 0938 \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\> 0939 \::digits 0940 0941 \tparam BitLength How many significant bits arguments have. 0942 \tparam DoIt \c true if #reflect_q will reflect, \c false if it should 0943 return its argument unchanged. 0944 \tparam Id An extra differentiator if multiple copies of this class 0945 template are mixed-in as base classes. Defaults to 0 if omitted. 0946 */ 0947 template < int BitLength, bool DoIt, int Id > 0948 class possible_reflector 0949 : public std::conditional< DoIt, reflector<BitLength>, 0950 non_reflector<BitLength> >::type 0951 { 0952 public: 0953 /** \brief The type to check for ID 0954 0955 This is a Boost integral constant indicating what ID number this 0956 instantiation used. 0957 */ 0958 typedef std::integral_constant<int, Id> id_type; 0959 }; 0960 0961 /** \brief Find the composite remainder update effect from a fixed bit 0962 sequence, for each potential sequence combination. 0963 0964 For each value between 0 and 2<sup><var>SubOrder</var></sup> - 1, 0965 computes the XOR mask corresponding to the composite effect they update 0966 the incoming remainder, which is the upper part of the dividend that 0967 gets (partially) pushed out of its register by the incoming value's 0968 bits. The composite value merges the \"partial products\" from each bit 0969 of the value being updated individually. 0970 0971 \pre \a Register is a built-in unsigned integer type 0972 \pre 0 \< \a SubOrder \<= \a register_length \<= 0973 std\::numeric_limits\<\a Register\>\::digits 0974 0975 \tparam SubOrder The number of low-order significant bits of the trial 0976 new dividends. 0977 \tparam Register The type used for representing the remainder and 0978 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0979 is used as the coefficient of <i>x<sup>i</sup></i>. 0980 0981 \param[in] register_length The number of significant low-order bits 0982 to be used from \a Register values. It is the order of the modulo-2 0983 polynomial remainder and one less than the divisor's order. 0984 \param[in] truncated_divisor The lowest coefficients of the divisor 0985 polynomial. The highest-order coefficient is omitted and always 0986 assumed to be 1. 0987 \param[in] reflect If \c false, read from the highest-order marked 0988 bit from a new dividend's bits and go down, as normal. Otherwise, 0989 proceed from the lowest-order bit and go up. 0990 0991 \return An array such that the element at index <var>i</var> is the 0992 composite effect XOR mask for value <var>i</var>. 0993 0994 \note This routine performs a modulo-2 polynomial division variant. 0995 The exclusive-or operations are applied in a different order, since 0996 that kind of operation is commutative and associative. It also 0997 assumes that the zero-valued augment string was applied before this 0998 step, which means that the updated remainder can be directly used as 0999 the final CRC. 1000 \todo Check that using the unaugmented-CRC division routines give the 1001 same composite mask table as using augmented-CRC routines. 1002 */ 1003 template < int SubOrder, typename Register > 1004 std::array< Register, (UINTMAX_C( 1 ) << SubOrder) > 1005 make_partial_xor_products_table( int register_length, Register 1006 truncated_divisor, bool reflect ) 1007 { 1008 std::array<Register, ( UINTMAX_C(1) << SubOrder )> result = { 0 }; 1009 1010 // Loop over every possible dividend value 1011 for ( typename boost::crc_detail::uint_t<SubOrder + 1>::fast dividend = 0u; 1012 dividend < result.size() ; ++dividend ) 1013 { 1014 Register remainder = 0u; 1015 1016 crc_modulo_word_update( register_length, remainder, dividend, 1017 truncated_divisor, SubOrder, false ); 1018 result[ reflect_optionally(dividend, reflect, SubOrder) ] = 1019 reflect_optionally( remainder, reflect, register_length ); 1020 } 1021 return result; 1022 } 1023 1024 /** \brief A mix-in class for the table of table-driven CRC algorithms 1025 1026 Encapsulates the parameters need to make a global (technically, 1027 class-static) table usuable in CRC algorithms, and generates said 1028 table. 1029 1030 \pre 0 \< \a SubOrder \<= Order \<= 1031 std\::numeric_limits\<uintmax_t\>\::digits 1032 1033 \tparam Order The order of the modulo-2 polynomial remainder and one 1034 less than the divisor's order. 1035 \tparam SubOrder The number of low-order significant bits of the trial 1036 new dividends. 1037 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1038 polynomial. The highest-order coefficient is omitted and always 1039 assumed to be 1. 1040 \tparam Reflect If \c false, read from the highest-order marked 1041 bit from a new dividend's bits and go down, as normal. Otherwise, 1042 proceed from the lowest-order bit and go up. 1043 */ 1044 template < int Order, int SubOrder, std::uintmax_t TruncatedPolynomial, 1045 bool Reflect > 1046 class crc_table_t 1047 { 1048 public: 1049 /** \brief The type to check for register bit length 1050 1051 This is a Boost integral constant indicating how many 1052 significant bits are in the remainder and (truncated) divisor. 1053 */ 1054 typedef std::integral_constant< int, Order > width_c; 1055 /** \brief The type to check for index-unit bit length 1056 1057 This is a Boost integral constant indicating how many 1058 significant bits are in the trial new dividends. 1059 */ 1060 typedef std::integral_constant< int, SubOrder > unit_width_c; 1061 /** \brief The type of registers 1062 1063 This is the output type for the partial-product map. 1064 */ 1065 typedef typename boost::crc_detail::uint_t< Order >::fast value_type; 1066 /** \brief The type to check the divisor 1067 1068 This is a Boost integral constant representing the (truncated) 1069 divisor. 1070 */ 1071 typedef std::integral_constant< value_type, TruncatedPolynomial > 1072 poly_c; 1073 /** \brief The type to check for reflection 1074 1075 This is a Boost integral constant representing whether input 1076 units should be read in reverse order. 1077 */ 1078 typedef std::integral_constant< bool, Reflect > refin_c; 1079 /** \brief The type to check for map size 1080 1081 This is a Boost integral constant representing the number of 1082 elements in the partial-product map, based on the unit size. 1083 */ 1084 typedef high_bit_mask_c< SubOrder > table_size_c; 1085 /** \brief The type of the unit TO partial-product map 1086 1087 This is the array type that takes units as the index and said unit's 1088 composite partial-product mask as the element. 1089 */ 1090 typedef std::array<value_type, table_size_c::value> array_type; 1091 /** \brief Create a global array for the mapping table 1092 1093 Creates an instance of a partial-product array with this class's 1094 parameters. 1095 1096 \return A reference to a immutable array giving the partial-product 1097 update XOR map for each potential sub-unit value. 1098 */ 1099 static array_type const & get_table() 1100 { 1101 static array_type const table = 1102 make_partial_xor_products_table<unit_width_c::value>( 1103 width_c::value, poly_c::value, refin_c::value ); 1104 1105 return table; 1106 } 1107 }; 1108 1109 /** \brief A mix-in class that handles direct (i.e. non-reflected) byte-fed 1110 table-driven CRC algorithms 1111 1112 This class template adds member functions #augmented_crc_update and 1113 #crc_update to update remainders from new input bytes. The bytes aren't 1114 reflected before processing. 1115 1116 \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\> 1117 \::digits 1118 1119 \tparam Order The order of the modulo-2 polynomial remainder and one 1120 less than the divisor's order. 1121 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1122 polynomial. The highest-order coefficient is omitted and always 1123 assumed to be 1. 1124 */ 1125 template < int Order, std::uintmax_t TruncatedPolynomial > 1126 class direct_byte_table_driven_crcs 1127 : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false> 1128 { 1129 typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false> 1130 base_type; 1131 1132 public: 1133 typedef typename base_type::value_type value_type; 1134 typedef typename base_type::array_type array_type; 1135 1136 /** \brief Compute the updated remainder after reading some bytes 1137 1138 The implementation reads from a table to speed-up applying 1139 augmented-CRC updates byte-wise. 1140 1141 \param remainder The pre-update remainder 1142 \param new_dividend_bytes The address where the new bytes start 1143 \param new_dividend_byte_count The number of new bytes to read 1144 1145 \return The updated remainder 1146 */ 1147 static value_type augmented_crc_update( value_type remainder, unsigned 1148 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1149 { 1150 static array_type const & table = base_type::get_table(); 1151 1152 while ( new_dividend_byte_count-- ) 1153 { 1154 // Locates the merged partial product based on the leading byte 1155 unsigned char const index = ( remainder >> (Order - CHAR_BIT) ) 1156 & UCHAR_MAX; 1157 1158 // Complete the multi-bit modulo-2 polynomial division 1159 remainder <<= CHAR_BIT; 1160 remainder |= *new_dividend_bytes++; 1161 remainder ^= table[ index ]; 1162 } 1163 1164 return remainder; 1165 } 1166 1167 /** \brief Compute the updated remainder after reading some bytes 1168 1169 The implementation reads from a table to speed-up applying 1170 unaugmented-CRC updates byte-wise. 1171 1172 \param remainder The pre-update remainder 1173 \param new_dividend_bytes The address where the new bytes start 1174 \param new_dividend_byte_count The number of new bytes to read 1175 1176 \return The updated remainder 1177 */ 1178 static value_type crc_update( value_type remainder, unsigned char 1179 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1180 { 1181 static array_type const & table = base_type::get_table(); 1182 1183 while ( new_dividend_byte_count-- ) 1184 { 1185 // Locates the merged partial product based on comparing the 1186 // leading and incoming bytes 1187 unsigned char const index = ( (remainder >> ( Order - CHAR_BIT 1188 )) & UCHAR_MAX ) ^ *new_dividend_bytes++; 1189 1190 // Complete the multi-bit altered modulo-2 polynomial division 1191 remainder <<= CHAR_BIT; 1192 remainder ^= table[ index ]; 1193 } 1194 1195 return remainder; 1196 } 1197 }; 1198 1199 /** \brief A mix-in class that handles reflected byte-fed, table-driven CRC 1200 algorithms 1201 1202 This class template adds member functions #augmented_crc_update and 1203 #crc_update to update remainders from new input bytes. The bytes are 1204 reflected before processing. 1205 1206 \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\> 1207 \::digits 1208 1209 \tparam Order The order of the modulo-2 polynomial remainder and one 1210 less than the divisor's order. 1211 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1212 polynomial. The highest-order coefficient is omitted and always 1213 assumed to be 1. 1214 */ 1215 template < int Order, std::uintmax_t TruncatedPolynomial > 1216 class reflected_byte_table_driven_crcs 1217 : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true> 1218 { 1219 typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true> 1220 base_type; 1221 1222 public: 1223 typedef typename base_type::value_type value_type; 1224 typedef typename base_type::array_type array_type; 1225 1226 /** \brief Compute the updated remainder after reading some bytes 1227 1228 The implementation reads from a table to speed-up applying 1229 reflecting augmented-CRC updates byte-wise. 1230 1231 \param remainder The pre-update remainder; since the bytes are 1232 being reflected, this remainder also has to be reflected 1233 \param new_dividend_bytes The address where the new bytes start 1234 \param new_dividend_byte_count The number of new bytes to read 1235 1236 \return The updated, reflected remainder 1237 */ 1238 static value_type augmented_crc_update( value_type remainder, unsigned 1239 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1240 { 1241 static array_type const & table = base_type::get_table(); 1242 1243 while ( new_dividend_byte_count-- ) 1244 { 1245 // Locates the merged partial product based on the leading byte 1246 // (which is at the low-order end for reflected remainders) 1247 unsigned char const index = remainder & UCHAR_MAX; 1248 1249 // Complete the multi-bit reflected modulo-2 polynomial division 1250 remainder >>= CHAR_BIT; 1251 remainder |= static_cast<value_type>( *new_dividend_bytes++ ) 1252 << ( Order - CHAR_BIT ); 1253 remainder ^= table[ index ]; 1254 } 1255 1256 return remainder; 1257 } 1258 1259 /** \brief Compute the updated remainder after reading some bytes 1260 1261 The implementation reads from a table to speed-up applying 1262 reflected unaugmented-CRC updates byte-wise. 1263 1264 \param remainder The pre-update remainder; since the bytes are 1265 being reflected, this remainder also has to be reflected 1266 \param new_dividend_bytes The address where the new bytes start 1267 \param new_dividend_byte_count The number of new bytes to read 1268 1269 \return The updated, reflected remainder 1270 */ 1271 static value_type crc_update( value_type remainder, unsigned char 1272 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1273 { 1274 static array_type const & table = base_type::get_table(); 1275 1276 while ( new_dividend_byte_count-- ) 1277 { 1278 // Locates the merged partial product based on comparing the 1279 // leading and incoming bytes 1280 unsigned char const index = ( remainder & UCHAR_MAX ) ^ 1281 *new_dividend_bytes++; 1282 1283 // Complete the multi-bit reflected altered modulo-2 polynomial 1284 // division 1285 remainder >>= CHAR_BIT; 1286 remainder ^= table[ index ]; 1287 } 1288 1289 return remainder; 1290 } 1291 }; 1292 1293 /** \brief Mix-in class for byte-fed, table-driven CRC algorithms with 1294 parameter values at least a byte in width 1295 1296 This class template adds member functions #augmented_crc_update and 1297 #crc_update to update remainders from new input bytes. The bytes may be 1298 reflected before processing, controlled by a compile-time parameter. 1299 1300 \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\> 1301 \::digits 1302 1303 \tparam Order The order of the modulo-2 polynomial remainder and one 1304 less than the divisor's order. 1305 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1306 polynomial. The highest-order coefficient is omitted and always 1307 assumed to be 1. 1308 \tparam Reflect If \c false, read from the highest-order bit from a new 1309 input byte and go down, as normal. Otherwise, proceed from the 1310 lowest-order bit and go up. 1311 */ 1312 template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect > 1313 class byte_table_driven_crcs 1314 : public std::conditional< Reflect, 1315 reflected_byte_table_driven_crcs<Order, TruncatedPolynomial>, 1316 direct_byte_table_driven_crcs<Order, TruncatedPolynomial> >::type 1317 { }; 1318 1319 /** \brief A mix-in class that handles direct (i.e. non-reflected) byte-fed 1320 CRC algorithms for sub-byte parameters 1321 1322 This class template adds member functions #augmented_crc_update and 1323 #crc_update to update remainders from new input bytes. The bytes aren't 1324 reflected before processing. 1325 1326 \pre 0 \< \a Order \< \c CHAR_BIT 1327 1328 \tparam Order The order of the modulo-2 polynomial remainder and one 1329 less than the divisor's order. 1330 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1331 polynomial. The highest-order coefficient is omitted and always 1332 assumed to be 1. 1333 */ 1334 template < int Order, std::uintmax_t TruncatedPolynomial > 1335 class direct_sub_byte_crcs 1336 : public crc_table_t<Order, Order, TruncatedPolynomial, false> 1337 { 1338 typedef crc_table_t<Order, Order, TruncatedPolynomial, false> 1339 base_type; 1340 1341 public: 1342 typedef typename base_type::width_c width_c; 1343 typedef typename base_type::value_type value_type; 1344 typedef typename base_type::poly_c poly_c; 1345 typedef typename base_type::array_type array_type; 1346 1347 /** \brief Compute the updated remainder after reading some bytes 1348 1349 The implementation reads from a table to speed-up applying 1350 augmented-CRC updates byte-wise. 1351 1352 \param remainder The pre-update remainder 1353 \param new_dividend_bytes The address where the new bytes start 1354 \param new_dividend_byte_count The number of new bytes to read 1355 1356 \return The updated remainder 1357 1358 \todo Use this function somewhere so I can test it. 1359 */ 1360 static value_type augmented_crc_update( value_type remainder, unsigned 1361 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1362 { 1363 //static array_type const & table = base_type::get_table(); 1364 1365 while ( new_dividend_byte_count-- ) 1366 { 1367 // Without a table, process each byte explicitly 1368 augmented_crc_modulo_word_update( width_c::value, remainder, 1369 *new_dividend_bytes++, poly_c::value, CHAR_BIT, false ); 1370 } 1371 1372 return remainder; 1373 } 1374 1375 /** \brief Compute the updated remainder after reading some bytes 1376 1377 The implementation reads from a table to speed-up applying 1378 unaugmented-CRC updates byte-wise. 1379 1380 \param remainder The pre-update remainder 1381 \param new_dividend_bytes The address where the new bytes start 1382 \param new_dividend_byte_count The number of new bytes to read 1383 1384 \return The updated remainder 1385 */ 1386 static value_type crc_update( value_type remainder, unsigned char 1387 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1388 { 1389 //static array_type const & table = base_type::get_table(); 1390 1391 while ( new_dividend_byte_count-- ) 1392 { 1393 // Without a table, process each byte explicitly 1394 crc_modulo_word_update( width_c::value, remainder, 1395 *new_dividend_bytes++, poly_c::value, CHAR_BIT, false ); 1396 } 1397 1398 return remainder; 1399 } 1400 }; 1401 1402 /** \brief A mix-in class that handles reflected byte-fed, CRC algorithms 1403 for sub-byte parameters 1404 1405 This class template adds member functions #augmented_crc_update and 1406 #crc_update to update remainders from new input bytes. The bytes are 1407 reflected before processing. 1408 1409 \pre 0 \< \a Order \< \c CHAR_BIT 1410 1411 \tparam Order The order of the modulo-2 polynomial remainder and one 1412 less than the divisor's order. 1413 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1414 polynomial. The highest-order coefficient is omitted and always 1415 assumed to be 1. 1416 */ 1417 template < int Order, std::uintmax_t TruncatedPolynomial > 1418 class reflected_sub_byte_crcs 1419 : public crc_table_t<Order, Order, TruncatedPolynomial, true> 1420 { 1421 typedef crc_table_t<Order, Order, TruncatedPolynomial, true> 1422 base_type; 1423 1424 public: 1425 typedef typename base_type::width_c width_c; 1426 typedef typename base_type::value_type value_type; 1427 typedef typename base_type::poly_c poly_c; 1428 typedef typename base_type::array_type array_type; 1429 1430 /** \brief Compute the updated remainder after reading some bytes 1431 1432 The implementation reads from a table to speed-up applying 1433 reflecting augmented-CRC updates byte-wise. 1434 1435 \param remainder The pre-update remainder; since the bytes are 1436 being reflected, this remainder also has to be reflected 1437 \param new_dividend_bytes The address where the new bytes start 1438 \param new_dividend_byte_count The number of new bytes to read 1439 1440 \return The updated, reflected remainder 1441 1442 \todo Use this function somewhere so I can test it. 1443 */ 1444 static value_type augmented_crc_update( value_type remainder, unsigned 1445 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1446 { 1447 //static array_type const & table = base_type::get_table(); 1448 1449 remainder = reflect_sub_byte( remainder, width_c::value ); 1450 while ( new_dividend_byte_count-- ) 1451 { 1452 // Without a table, process each byte explicitly 1453 augmented_crc_modulo_word_update( width_c::value, remainder, 1454 *new_dividend_bytes++, poly_c::value, CHAR_BIT, true ); 1455 } 1456 remainder = reflect_sub_byte( remainder, width_c::value ); 1457 1458 return remainder; 1459 } 1460 1461 /** \brief Compute the updated remainder after reading some bytes 1462 1463 The implementation reads from a table to speed-up applying 1464 reflected unaugmented-CRC updates byte-wise. 1465 1466 \param remainder The pre-update remainder; since the bytes are 1467 being reflected, this remainder also has to be reflected 1468 \param new_dividend_bytes The address where the new bytes start 1469 \param new_dividend_byte_count The number of new bytes to read 1470 1471 \return The updated, reflected remainder 1472 */ 1473 static value_type crc_update( value_type remainder, unsigned char 1474 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1475 { 1476 //static array_type const & table = base_type::get_table(); 1477 1478 remainder = reflect_sub_byte( remainder, width_c::value ); 1479 while ( new_dividend_byte_count-- ) 1480 { 1481 // Without a table, process each byte explicitly 1482 crc_modulo_word_update( width_c::value, remainder, 1483 *new_dividend_bytes++, poly_c::value, CHAR_BIT, true ); 1484 } 1485 remainder = reflect_sub_byte( remainder, width_c::value ); 1486 1487 return remainder; 1488 } 1489 }; 1490 1491 /** \brief Mix-in class for byte-fed, table-driven CRC algorithms with 1492 sub-byte parameters 1493 1494 This class template adds member functions #augmented_crc_update and 1495 #crc_update to update remainders from new input bytes. The bytes may be 1496 reflected before processing, controlled by a compile-time parameter. 1497 1498 \pre 0 \< \a Order \< \c CHAR_BIT 1499 1500 \tparam Order The order of the modulo-2 polynomial remainder and one 1501 less than the divisor's order. 1502 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1503 polynomial. The highest-order coefficient is omitted and always 1504 assumed to be 1. 1505 \tparam Reflect If \c false, read from the highest-order bit from a new 1506 input byte and go down, as normal. Otherwise, proceed from the 1507 lowest-order bit and go up. 1508 */ 1509 template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect > 1510 class sub_byte_crcs 1511 : public std::conditional< Reflect, 1512 reflected_sub_byte_crcs<Order, TruncatedPolynomial>, 1513 direct_sub_byte_crcs<Order, TruncatedPolynomial> >::type 1514 { }; 1515 1516 /** This class template adds member functions #augmented_crc_update and 1517 #crc_update to update remainders from new input bytes. The bytes may be 1518 reflected before processing, controlled by a compile-time parameter. 1519 1520 \pre 0 \< \a Order \<= \c std\::numeric_limits\<uintmax_t\>\::digits 1521 1522 \tparam Order The order of the modulo-2 polynomial remainder and one 1523 less than the divisor's order. 1524 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1525 polynomial. The highest-order coefficient is omitted and always 1526 assumed to be 1. 1527 \tparam Reflect If \c false, read from the highest-order bit from a new 1528 input byte and go down, as normal. Otherwise, proceed from the 1529 lowest-order bit and go up. 1530 \tparam Id An extra differentiator if multiple copies of this class 1531 template are mixed-in as base classes. Defaults to 0 if omitted. 1532 */ 1533 template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect, 1534 int Id > 1535 class crc_driver 1536 : public std::conditional< (Order < CHAR_BIT), sub_byte_crcs<Order, 1537 TruncatedPolynomial, Reflect>, byte_table_driven_crcs<Order, 1538 TruncatedPolynomial, Reflect> >::type 1539 { 1540 public: 1541 /** \brief The type to check for ID 1542 1543 This is a Boost integral constant indicating what ID number this 1544 instantiation used. 1545 */ 1546 typedef std::integral_constant<int, Id> id_type; 1547 }; 1548 1549 1550 } // namespace detail 1551 //! \endcond 1552 1553 1554 // Simple CRC class function definitions -----------------------------------// 1555 1556 /** Constructs a \c crc_basic object with at least the required parameters to a 1557 particular CRC formula to be processed upon receiving input. 1558 1559 \param[in] truncated_polynomial The lowest coefficients of the divisor 1560 polynomial. The highest-order coefficient is omitted and always assumed 1561 to be 1. (\e Poly from the RMCA) 1562 \param[in] initial_remainder The (unaugmented) initial state of the 1563 polynomial remainder. Defaults to \c 0 if omitted. (\e Init from the 1564 RMCA) 1565 \param[in] final_xor_value The (XOR) bit-mask to be applied to the output 1566 remainder, after possible reflection but before returning. Defaults to 1567 \c 0 (i.e. no bit changes) if omitted. (\e XorOut from the RMCA) 1568 \param[in] reflect_input If \c true, input bytes are read lowest-order bit 1569 first, otherwise highest-order bit first. Defaults to \c false if 1570 omitted. (\e RefIn from the RMCA) 1571 \param[in] reflect_remainder If \c true, the output remainder is reflected 1572 before the XOR-mask. Defaults to \c false if omitted. (\e RefOut from 1573 the RMCA) 1574 1575 \post <code><var>truncated_polynomial</var> == 1576 this->get_truncated_polynominal()</code> 1577 \post <code><var>initial_remainder</var> == 1578 this->get_initial_remainder()</code> 1579 \post <code><var>final_xor_value</var> == 1580 this->get_final_xor_value()</code> 1581 \post <code><var>reflect_input</var> == 1582 this->get_reflect_input()</code> 1583 \post <code><var>reflect_remainder</var> == 1584 this->get_reflect_remainder()</code> 1585 \post <code><var>initial_remainder</var> == 1586 this->get_interim_remainder()</code> 1587 \post <code>(<var>reflect_remainder</var> ? 1588 REFLECT(<var>initial_remainder</var>) : <var>initial_remainder</var>) ^ 1589 <var>final_xor_value</var> == this->checksum()</code> 1590 */ 1591 template < std::size_t Bits > 1592 inline 1593 crc_basic<Bits>::crc_basic 1594 ( 1595 value_type truncated_polynomial, 1596 value_type initial_remainder, // = 0 1597 value_type final_xor_value, // = 0 1598 bool reflect_input, // = false 1599 bool reflect_remainder // = false 1600 ) 1601 : rem_( initial_remainder ), poly_( truncated_polynomial ) 1602 , init_( initial_remainder ), final_( final_xor_value ) 1603 , rft_in_( reflect_input ), rft_out_( reflect_remainder ) 1604 { 1605 } 1606 1607 /** Returns a representation of the polynomial divisor. The value of the 1608 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 1609 x<sup>i</sup> term. The omitted bit for x<sup>(#bit_count)</sup> term is 1610 always 1. 1611 1612 \return The bit-packed list of coefficients. If the bit-length of 1613 #value_type exceeds #bit_count, the values of higher-placed bits should be 1614 ignored (even any for x<sup>(#bit_count)</sup>) since they're unregulated. 1615 */ 1616 template < std::size_t Bits > 1617 inline 1618 typename crc_basic<Bits>::value_type 1619 crc_basic<Bits>::get_truncated_polynominal 1620 ( 1621 ) const 1622 { 1623 return poly_; 1624 } 1625 1626 /** Returns a representation of the polynomial remainder before any input has 1627 been submitted. The value of the 2<sup>i</sup> bit is the value of the 1628 coefficient of the polynomial's x<sup>i</sup> term. 1629 1630 \return The bit-packed list of coefficients. If the bit-length of 1631 #value_type exceeds #bit_count, the values of higher-placed bits should be 1632 ignored since they're unregulated. 1633 */ 1634 template < std::size_t Bits > 1635 inline 1636 typename crc_basic<Bits>::value_type 1637 crc_basic<Bits>::get_initial_remainder 1638 ( 1639 ) const 1640 { 1641 return init_; 1642 } 1643 1644 /** Returns the mask to be used during creation of a checksum. The mask is used 1645 for an exclusive-or (XOR) operation applied bit-wise to the interim 1646 remainder representation (after any reflection, if #get_reflect_remainder() 1647 returns \c true). 1648 1649 \return The bit-mask. If the bit-length of #value_type exceeds #bit_count, 1650 the values of higher-placed bits should be ignored since they're 1651 unregulated. 1652 */ 1653 template < std::size_t Bits > 1654 inline 1655 typename crc_basic<Bits>::value_type 1656 crc_basic<Bits>::get_final_xor_value 1657 ( 1658 ) const 1659 { 1660 return final_; 1661 } 1662 1663 /** Returns a whether or not a submitted byte will be \"reflected\" before it is 1664 used to update the interim remainder. Only the byte-wise operations 1665 #process_byte, #process_block, and #process_bytes are affected. 1666 1667 \retval true Input bytes will be read starting from the lowest-order bit. 1668 \retval false Input bytes will be read starting from the highest-order bit. 1669 */ 1670 template < std::size_t Bits > 1671 inline 1672 bool 1673 crc_basic<Bits>::get_reflect_input 1674 ( 1675 ) const 1676 { 1677 return rft_in_; 1678 } 1679 1680 /** Indicates if the interim remainder will be \"reflected\" before it is passed 1681 to the XOR-mask stage when returning a checksum. 1682 1683 \retval true The interim remainder is reflected before further work. 1684 \retval false The interim remainder is applied to the XOR-mask as-is. 1685 */ 1686 template < std::size_t Bits > 1687 inline 1688 bool 1689 crc_basic<Bits>::get_reflect_remainder 1690 ( 1691 ) const 1692 { 1693 return rft_out_; 1694 } 1695 1696 /** Returns a representation of the polynomial remainder after all the input 1697 submissions since construction or the last #reset call. The value of the 1698 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 1699 x<sup>i</sup> term. If CRC processing gets interrupted here, retain the 1700 value returned, and use it to start up the next CRC computer where you left 1701 off (with #reset(value_type) or construction). The next computer has to 1702 have its other parameters compatible with this computer. 1703 1704 \return The bit-packed list of coefficients. If the bit-length of 1705 #value_type exceeds #bit_count, the values of higher-placed bits should be 1706 ignored since they're unregulated. No output processing (reflection or 1707 XOR mask) has been applied to the value. 1708 */ 1709 template < std::size_t Bits > 1710 inline 1711 typename crc_basic<Bits>::value_type 1712 crc_basic<Bits>::get_interim_remainder 1713 ( 1714 ) const 1715 { 1716 return rem_ & detail::low_bits_mask_c<bit_count>::value; 1717 } 1718 1719 /** Changes the interim polynomial remainder to \a new_rem, purging any 1720 influence previously submitted input has had. The value of the 1721 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 1722 x<sup>i</sup> term. 1723 1724 \param[in] new_rem The (unaugmented) state of the polynomial remainder 1725 starting from this point, with no output processing applied. 1726 1727 \post <code><var>new_rem</var> == this->get_interim_remainder()</code> 1728 \post <code>((this->get_reflect_remainder() ? 1729 REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^ 1730 this->get_final_xor_value()) == this->checksum()</code> 1731 */ 1732 template < std::size_t Bits > 1733 inline 1734 void 1735 crc_basic<Bits>::reset 1736 ( 1737 value_type new_rem 1738 ) 1739 { 1740 rem_ = new_rem; 1741 } 1742 1743 /** Changes the interim polynomial remainder to the initial remainder given 1744 during construction, purging any influence previously submitted input has 1745 had. The value of the 2<sup>i</sup> bit is the value of the coefficient of 1746 the polynomial's x<sup>i</sup> term. 1747 1748 \post <code>this->get_initial_remainder() == 1749 this->get_interim_remainder()</code> 1750 \post <code>((this->get_reflect_remainder() ? 1751 REFLECT(this->get_initial_remainder()) : 1752 this->get_initial_remainder()) ^ this->get_final_xor_value()) 1753 == this->checksum()</code> 1754 */ 1755 template < std::size_t Bits > 1756 inline 1757 void 1758 crc_basic<Bits>::reset 1759 ( 1760 ) 1761 { 1762 this->reset( this->get_initial_remainder() ); 1763 } 1764 1765 /** Updates the interim remainder with a single altered-CRC-division step. 1766 1767 \param[in] bit The new input bit. 1768 1769 \post The interim remainder is updated though a modulo-2 polynomial 1770 division, where the division steps are altered for unaugmented CRCs. 1771 */ 1772 template < std::size_t Bits > 1773 inline 1774 void 1775 crc_basic<Bits>::process_bit 1776 ( 1777 bool bit 1778 ) 1779 { 1780 detail::crc_modulo_update( bit_count, rem_, bit, poly_ ); 1781 } 1782 1783 /** Updates the interim remainder with several altered-CRC-division steps. Each 1784 bit is processed separately, starting from the one at the 1785 2<sup><var>bit_length</var> - 1</sup> place, then proceeding down to the 1786 lowest-placed bit. Any order imposed by 1787 <code>this->get_reflect_input()</code> is ignored. 1788 1789 \pre 0 \< \a bit_length \<= \c CHAR_BIT 1790 1791 \param[in] bits The byte containing the new input bits. 1792 \param[in] bit_length The number of bits in the byte to be read. 1793 1794 \post The interim remainder is updated though \a bit_length modulo-2 1795 polynomial divisions, where the division steps are altered for unaugmented 1796 CRCs. 1797 */ 1798 template < std::size_t Bits > 1799 void 1800 crc_basic<Bits>::process_bits 1801 ( 1802 unsigned char bits, 1803 std::size_t bit_length 1804 ) 1805 { 1806 // ignore the bits above the ones we want 1807 bits <<= CHAR_BIT - bit_length; 1808 1809 // compute the CRC for each bit, starting with the upper ones 1810 unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u ); 1811 for ( std::size_t i = bit_length ; i > 0u ; --i, bits <<= 1u ) 1812 { 1813 process_bit( (bits & high_bit_mask) != 0 ); 1814 } 1815 } 1816 1817 /** Updates the interim remainder with a byte's worth of altered-CRC-division 1818 steps. The bits within the byte are processed from the highest place down 1819 if <code>this->get_reflect_input()</code> is \c false, and lowest place 1820 up otherwise. 1821 1822 \param[in] byte The new input byte. 1823 1824 \post The interim remainder is updated though \c CHAR_BIT modulo-2 1825 polynomial divisions, where the division steps are altered for unaugmented 1826 CRCs. 1827 */ 1828 template < std::size_t Bits > 1829 inline 1830 void 1831 crc_basic<Bits>::process_byte 1832 ( 1833 unsigned char byte 1834 ) 1835 { 1836 process_bits( (rft_in_ ? detail::reflect_byte( byte ) : byte), CHAR_BIT ); 1837 } 1838 1839 /** Updates the interim remainder with several bytes' worth of 1840 altered-CRC-division steps. The bits within each byte are processed from 1841 the highest place down if <code>this->get_reflect_input()</code> is 1842 \c false, and lowest place up otherwise. The bytes themselves are processed 1843 starting from the one pointed by \a bytes_begin until \a bytes_end is 1844 reached through forward iteration, treating the two pointers as if they 1845 point to <code>unsigned char</code> objects. 1846 1847 \pre \a bytes_end has to equal \a bytes_begin if the latter is \c NULL or 1848 otherwise doesn't point to a valid buffer. 1849 \pre \a bytes_end, if not equal to \a bytes_begin, has to point within or 1850 one-byte-past the same buffer \a bytes_begin points into. 1851 \pre \a bytes_end has to be reachable from \a bytes_begin through a finite 1852 number of forward byte-pointer increments. 1853 1854 \param[in] bytes_begin The address where the memory block begins. 1855 \param[in] bytes_end Points to one-byte past the address of the memory 1856 block's last byte, or \a bytes_begin if no bytes are to be read. 1857 1858 \post The interim remainder is updated though <code>CHAR_BIT * (((unsigned 1859 char const *) bytes_end) - ((unsigned char const *) bytes_begin))</code> 1860 modulo-2 polynomial divisions, where the division steps are altered for 1861 unaugmented CRCs. 1862 */ 1863 template < std::size_t Bits > 1864 void 1865 crc_basic<Bits>::process_block 1866 ( 1867 void const * bytes_begin, 1868 void const * bytes_end 1869 ) 1870 { 1871 for ( unsigned char const * p 1872 = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p ) 1873 { 1874 process_byte( *p ); 1875 } 1876 } 1877 1878 /** Updates the interim remainder with several bytes' worth of 1879 altered-CRC-division steps. The bits within each byte are processed from 1880 the highest place down if <code>this->get_reflect_input()</code> is 1881 \c false, and lowest place up otherwise. The bytes themselves are processed 1882 starting from the one pointed by \a buffer, forward-iterated (as if the 1883 pointed-to objects were of <code>unsigned char</code>) until \a byte_count 1884 bytes are read. 1885 1886 \pre \a byte_count has to equal 0 if \a buffer is \c NULL or otherwise 1887 doesn't point to valid memory. 1888 \pre If \a buffer points within valid memory, then that block has to have 1889 at least \a byte_count more valid bytes allocated from that point. 1890 1891 \param[in] buffer The address where the memory block begins. 1892 \param[in] byte_count The number of bytes in the memory block. 1893 1894 \post The interim remainder is updated though <code>CHAR_BIT * 1895 <var>byte_count</var></code> modulo-2 polynomial divisions, where the 1896 division steps are altered for unaugmented CRCs. 1897 */ 1898 template < std::size_t Bits > 1899 inline 1900 void 1901 crc_basic<Bits>::process_bytes 1902 ( 1903 void const * buffer, 1904 std::size_t byte_count 1905 ) 1906 { 1907 unsigned char const * const b = static_cast<unsigned char const *>( 1908 buffer ); 1909 1910 process_block( b, b + byte_count ); 1911 } 1912 1913 /** Computes the checksum of all the submitted bits since construction or the 1914 last call to #reset. The checksum will be the raw checksum, i.e. the 1915 (interim) remainder after all the modulo-2 polynomial division, plus any 1916 output processing. 1917 1918 \return <code>(this->get_reflect_remainder() ? 1919 REFLECT(this->get_interim_remainder()) : 1920 this->get_interim_remainder()) ^ this->get_final_xor_value()</code> 1921 1922 \note Since checksums are meant to be compared, any higher-placed bits 1923 (when the bit-length of #value_type exceeds #bit_count) will be set to 0. 1924 */ 1925 template < std::size_t Bits > 1926 inline 1927 typename crc_basic<Bits>::value_type 1928 crc_basic<Bits>::checksum 1929 ( 1930 ) const 1931 { 1932 return ( (rft_out_ ? detail::reflect_unsigned( rem_, bit_count ) : 1933 rem_) ^ final_ ) & detail::low_bits_mask_c<bit_count>::value; 1934 } 1935 1936 1937 // Optimized CRC class function definitions --------------------------------// 1938 1939 // Macro to compact code 1940 #define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \ 1941 FinalXor, ReflectIn, ReflectRem> 1942 1943 /** Constructs a \c crc_optimal object with a particular CRC formula to be 1944 processed upon receiving input. The initial remainder may be overridden. 1945 1946 \param[in] init_rem The (unaugmented) initial state of the polynomial 1947 remainder. Defaults to #initial_remainder if omitted. 1948 1949 \post <code>#truncated_polynominal == 1950 this->get_truncated_polynominal()</code> 1951 \post <code>#initial_remainder == this->get_initial_remainder()</code> 1952 \post <code>#final_xor_value == this->get_final_xor_value()</code> 1953 \post <code>#reflect_input == this->get_reflect_input()</code> 1954 \post <code>#reflect_remainder == this->get_reflect_remainder()</code> 1955 \post <code><var>init_rem</var> == this->get_interim_remainder()</code> 1956 \post <code>(#reflect_remainder ? REFLECT(<var>init_rem</var>) : 1957 <var>init_rem</var>) ^ #final_xor_value == this->checksum()</code> 1958 */ 1959 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1960 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1961 bool ReflectIn, bool ReflectRem > 1962 inline 1963 BOOST_CRC_OPTIMAL_NAME::crc_optimal 1964 ( 1965 value_type init_rem // = initial_remainder 1966 ) 1967 : rem_( reflect_i_type::reflect_q(init_rem) ) 1968 { 1969 } 1970 1971 //! \copydetails boost::crc_basic::get_truncated_polynominal 1972 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1973 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1974 bool ReflectIn, bool ReflectRem > 1975 inline 1976 typename BOOST_CRC_OPTIMAL_NAME::value_type 1977 BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal 1978 ( 1979 ) const 1980 { 1981 return truncated_polynominal; 1982 } 1983 1984 //! \copydetails boost::crc_basic::get_initial_remainder 1985 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1986 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1987 bool ReflectIn, bool ReflectRem > 1988 inline 1989 typename BOOST_CRC_OPTIMAL_NAME::value_type 1990 BOOST_CRC_OPTIMAL_NAME::get_initial_remainder 1991 ( 1992 ) const 1993 { 1994 return initial_remainder; 1995 } 1996 1997 //! \copydetails boost::crc_basic::get_final_xor_value 1998 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1999 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2000 bool ReflectIn, bool ReflectRem > 2001 inline 2002 typename BOOST_CRC_OPTIMAL_NAME::value_type 2003 BOOST_CRC_OPTIMAL_NAME::get_final_xor_value 2004 ( 2005 ) const 2006 { 2007 return final_xor_value; 2008 } 2009 2010 //! \copydetails boost::crc_basic::get_reflect_input 2011 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2012 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2013 bool ReflectIn, bool ReflectRem > 2014 inline 2015 bool 2016 BOOST_CRC_OPTIMAL_NAME::get_reflect_input 2017 ( 2018 ) const 2019 { 2020 return reflect_input; 2021 } 2022 2023 //! \copydetails boost::crc_basic::get_reflect_remainder 2024 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2025 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2026 bool ReflectIn, bool ReflectRem > 2027 inline 2028 bool 2029 BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder 2030 ( 2031 ) const 2032 { 2033 return reflect_remainder; 2034 } 2035 2036 //! \copydetails boost::crc_basic::get_interim_remainder 2037 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2038 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2039 bool ReflectIn, bool ReflectRem > 2040 inline 2041 typename BOOST_CRC_OPTIMAL_NAME::value_type 2042 BOOST_CRC_OPTIMAL_NAME::get_interim_remainder 2043 ( 2044 ) const 2045 { 2046 // Interim remainder should be _un_-reflected, so we have to undo it. 2047 return reflect_i_type::reflect_q( rem_ ) & 2048 detail::low_bits_mask_c<bit_count>::value; 2049 } 2050 2051 /** Changes the interim polynomial remainder to \a new_rem, purging any 2052 influence previously submitted input has had. The value of the 2053 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 2054 x<sup>i</sup> term. 2055 2056 \param[in] new_rem The (unaugmented) state of the polynomial remainder 2057 starting from this point, with no output processing applied. Defaults to 2058 <code>this->get_initial_remainder()</code> if omitted. 2059 2060 \post <code><var>new_rem</var> == this->get_interim_remainder()</code> 2061 \post <code>((this->get_reflect_remainder() ? 2062 REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^ 2063 this->get_final_xor_value()) == this->checksum()</code> 2064 */ 2065 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2066 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2067 bool ReflectIn, bool ReflectRem > 2068 inline 2069 void 2070 BOOST_CRC_OPTIMAL_NAME::reset 2071 ( 2072 value_type new_rem // = initial_remainder 2073 ) 2074 { 2075 rem_ = reflect_i_type::reflect_q( new_rem ); 2076 } 2077 2078 /** \copydetails boost::crc_basic::process_byte 2079 2080 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2081 remainder changes (as XOR masks) to speed computation when reading data 2082 byte-wise. 2083 */ 2084 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2085 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2086 bool ReflectIn, bool ReflectRem > 2087 inline 2088 void 2089 BOOST_CRC_OPTIMAL_NAME::process_byte 2090 ( 2091 unsigned char byte 2092 ) 2093 { 2094 process_bytes( &byte, sizeof(byte) ); 2095 } 2096 2097 /** \copydetails boost::crc_basic::process_block 2098 2099 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2100 remainder changes (as XOR masks) to speed computation when reading data 2101 byte-wise. 2102 */ 2103 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2104 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2105 bool ReflectIn, bool ReflectRem > 2106 inline 2107 void 2108 BOOST_CRC_OPTIMAL_NAME::process_block 2109 ( 2110 void const * bytes_begin, 2111 void const * bytes_end 2112 ) 2113 { 2114 process_bytes( bytes_begin, static_cast<unsigned char const *>(bytes_end) - 2115 static_cast<unsigned char const *>(bytes_begin) ); 2116 } 2117 2118 /** \copydetails boost::crc_basic::process_bytes 2119 2120 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2121 remainder changes (as XOR masks) to speed computation when reading data 2122 byte-wise. 2123 */ 2124 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2125 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2126 bool ReflectIn, bool ReflectRem > 2127 inline 2128 void 2129 BOOST_CRC_OPTIMAL_NAME::process_bytes 2130 ( 2131 void const * buffer, 2132 std::size_t byte_count 2133 ) 2134 { 2135 rem_ = crc_table_type::crc_update( rem_, static_cast<unsigned char const 2136 *>(buffer), byte_count ); 2137 } 2138 2139 //! \copydetails boost::crc_basic::checksum 2140 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2141 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2142 bool ReflectIn, bool ReflectRem > 2143 inline 2144 typename BOOST_CRC_OPTIMAL_NAME::value_type 2145 BOOST_CRC_OPTIMAL_NAME::checksum 2146 ( 2147 ) const 2148 { 2149 return ( reflect_o_type::reflect_q(rem_) ^ get_final_xor_value() ) 2150 & detail::low_bits_mask_c<bit_count>::value; 2151 } 2152 2153 /** Updates the interim remainder with a byte's worth of altered-CRC-division 2154 steps. The bits within the byte are processed from the highest place down 2155 if <code>this->get_reflect_input()</code> is \c false, and lowest place 2156 up otherwise. This function is meant to present a function-object interface 2157 to code that wants to process a stream of bytes with 2158 <code>std::for_each</code> or similar range-processing algorithms. Since 2159 some of these algorithms takes their function object by value, make sure to 2160 copy back the result to this object so the updates can be remembered. 2161 2162 \param[in] byte The new input byte. 2163 2164 \post The interim remainder is updated though \c CHAR_BIT modulo-2 2165 polynomial divisions, where the division steps are altered for unaugmented 2166 CRCs. 2167 2168 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2169 remainder changes (as XOR masks) to speed computation when reading data 2170 byte-wise. 2171 */ 2172 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2173 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2174 bool ReflectIn, bool ReflectRem > 2175 inline 2176 void 2177 BOOST_CRC_OPTIMAL_NAME::operator () 2178 ( 2179 unsigned char byte 2180 ) 2181 { 2182 process_byte( byte ); 2183 } 2184 2185 /** Computes the checksum of all the submitted bits since construction or the 2186 last call to #reset. The checksum will be the raw checksum, i.e. the 2187 (interim) remainder after all the modulo-2 polynomial division, plus any 2188 output processing. This function is meant to present a function-object 2189 interface to code that wants to receive data like 2190 <code>std::generate_n</code> or similar data-processing algorithms. Note 2191 that if this object is used as a generator multiple times without an 2192 intervening mutating operation, the same value will always be returned. 2193 2194 \return <code>(this->get_reflect_remainder() ? 2195 REFLECT(this->get_interim_remainder()) : 2196 this->get_interim_remainder()) ^ this->get_final_xor_value()</code> 2197 2198 \note Since checksums are meant to be compared, any higher-placed bits 2199 (when the bit-length of #value_type exceeds #bit_count) will be set to 0. 2200 */ 2201 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2202 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2203 bool ReflectIn, bool ReflectRem > 2204 inline 2205 typename BOOST_CRC_OPTIMAL_NAME::value_type 2206 BOOST_CRC_OPTIMAL_NAME::operator () 2207 ( 2208 ) const 2209 { 2210 return checksum(); 2211 } 2212 2213 2214 // CRC computation function definition -------------------------------------// 2215 2216 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and 2217 \a byte_count describe a memory block representing the polynomial dividend. 2218 The division steps are altered so the result directly gives a checksum, 2219 without need to augment the memory block with scratch-space bytes. The 2220 first byte is considered the highest order, going down for subsequent bytes. 2221 2222 \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits 2223 2224 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 2225 the RMCA) 2226 \tparam TruncPoly The lowest coefficients of the divisor polynomial. The 2227 highest-order coefficient is omitted and always assumed to be 1. 2228 (\e Poly from the RMCA) 2229 \tparam InitRem The (unaugmented) initial state of the polynomial 2230 remainder. (\e Init from the RMCA) 2231 \tparam FinalXor The (XOR) bit-mask to be applied to the output remainder, 2232 after possible reflection but before returning. (\e XorOut from the RMCA) 2233 \tparam ReflectIn If \c True, input bytes are read lowest-order bit first, 2234 otherwise highest-order bit first. (\e RefIn from the RMCA) 2235 \tparam ReflectRem If \c True, the output remainder is reflected before the 2236 XOR-mask. (\e RefOut from the RMCA) 2237 2238 \param[in] buffer The address where the memory block begins. 2239 \param[in] byte_count The number of bytes in the memory block. 2240 2241 \return The checksum, which is the last (interim) remainder plus any output 2242 processing. 2243 2244 \note Unaugmented-style CRC runs perform modulo-2 polynomial division in 2245 an altered order. The trailing \a Bits number of zero-valued bits needed 2246 to extracted an (unprocessed) checksum is virtually moved to near the 2247 beginning of the message. This is OK since the XOR operation is 2248 commutative and associative. It also means that you can get a checksum 2249 anytime. Since data is being read byte-wise, a table of pre-computed 2250 remainder changes (as XOR masks) can be used to speed computation. 2251 2252 */ 2253 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2254 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2255 bool ReflectIn, bool ReflectRem > 2256 inline 2257 typename crc_detail::uint_t<Bits>::fast 2258 crc 2259 ( 2260 void const * buffer, 2261 std::size_t byte_count 2262 ) 2263 { 2264 BOOST_CRC_OPTIMAL_NAME computer; 2265 computer.process_bytes( buffer, byte_count ); 2266 return computer.checksum(); 2267 } 2268 2269 2270 // Augmented-message CRC computation function definition -------------------// 2271 2272 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and 2273 \a byte_count describe a memory block representing the polynomial dividend. 2274 The first byte is considered the highest order, going down for subsequent 2275 bytes. Within a byte, the highest-order bit is read first (corresponding to 2276 \e RefIn = \c False in the RMCA). Check the other parts of this function's 2277 documentation to see how a checksum can be gained and/or used. 2278 2279 \pre 0 \< \a Bits \<= \c std\::numeric_limit\<uintmax_t\>\::digits 2280 2281 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 2282 the RMCA) 2283 \tparam TruncPoly The lowest coefficients of the divisor polynomial. The 2284 highest-order coefficient is omitted and always assumed to be 1. 2285 (\e Poly from the RMCA) 2286 2287 \param[in] buffer The address where the memory block begins. 2288 \param[in] byte_count The number of bytes in the memory block. 2289 \param[in] initial_remainder The initial state of the polynomial 2290 remainder, defaulting to zero if omitted. If you are reading a memory 2291 block in multiple runs, put the return value of the previous run here. 2292 (Note that initial-remainders given by RMCA parameter lists, as 2293 \e Init, assume that the initial remainder is in its \b unaugmented state, 2294 so you would need to convert the value to make it suitable for this 2295 function. I currently don't provide a conversion routine.) 2296 2297 \return The interim remainder, if no augmentation is used. A special value 2298 if augmentation is used (see the notes). No output processing is done on 2299 the value. (In RMCA terms, \e RefOut is \c False and \e XorOut is \c 0.) 2300 2301 \note Augmented-style CRC runs use straight-up modulo-2 polynomial 2302 division. Since data is being read byte-wise, a table of pre-computed 2303 remainder changes (as XOR masks) can be used to speed computation. 2304 \note Reading just a memory block will yield an interim remainder, and not 2305 the final checksum. To get that checksum, allocate \a Bits / \c CHAR_BIT 2306 bytes directly after the block and fill them with zero values, then extend 2307 \a byte_count to include those extra bytes. A data block is corrupt if 2308 the return value doesn't equal your separately given checksum. 2309 \note Another way to perform a check is use the zero-byte extension method, 2310 but replace the zero values with your separately-given checksum. The 2311 checksum must be loaded in big-endian order. Here corruption, in either 2312 the data block or the given checksum, is confirmed if the return value is 2313 not zero. 2314 \note The two checksum techniques assume the CRC-run is performed bit-wise, 2315 while this function works byte-wise. That means that the techniques can 2316 be used only if \c CHAR_BIT divides \a Bits evenly! 2317 */ 2318 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > 2319 typename crc_detail::uint_t<Bits>::fast 2320 augmented_crc 2321 ( 2322 void const * buffer, 2323 std::size_t byte_count, 2324 typename crc_detail::uint_t<Bits>::fast initial_remainder // = 0u 2325 ) 2326 { 2327 return detail::low_bits_mask_c<Bits>::value & 2328 detail::byte_table_driven_crcs<Bits, TruncPoly, false>:: 2329 augmented_crc_update( initial_remainder, static_cast<unsigned char const 2330 *>(buffer), byte_count ); 2331 } 2332 2333 2334 } // namespace boost 2335 2336 2337 // Undo header-private macros 2338 #undef BOOST_CRC_OPTIMAL_NAME 2339 #undef BOOST_CRC_PARM_TYPE 2340 2341 2342 #endif // BOOST_CRC_HPP 2343
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |