| [29] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> | 
|---|
 | 2 | <html> | 
|---|
 | 3 | <head> | 
|---|
 | 4 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | 
|---|
 | 5 | <title>Boost CRC Library Documentation</title> | 
|---|
 | 6 | </head> | 
|---|
 | 7 |  | 
|---|
 | 8 | <body text="black" bgcolor="white" link="blue" vlink="purple" alink="red"> | 
|---|
 | 9 |  | 
|---|
 | 10 | <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" | 
|---|
 | 11 | align="middle" width="277" height="86">Header <cite><<a | 
|---|
 | 12 | href="../../boost/crc.hpp">boost/crc.hpp</a>></cite></h1> | 
|---|
 | 13 |  | 
|---|
 | 14 | <p>The header <cite><<a | 
|---|
 | 15 | href="../../boost/crc.hpp">boost/crc.hpp</a>></cite> supplies two | 
|---|
 | 16 | class templates in namespace <code>boost</code>.  These templates define | 
|---|
 | 17 | objects that can compute the <dfn>CRC</dfn>, or cyclic redundancy code | 
|---|
 | 18 | (or check), of a given stream of data.  The header also supplies | 
|---|
 | 19 | function templates to compute a CRC in one step.</p> | 
|---|
 | 20 |  | 
|---|
 | 21 | <h2><a name="contents">Contents</a></h2> | 
|---|
 | 22 |  | 
|---|
 | 23 | <ol> | 
|---|
 | 24 |         <li><a href="#contents">Contents</a></li> | 
|---|
 | 25 |         <li><a href="#header">Header Synopsis</a></li> | 
|---|
 | 26 |         <li><a href="#rationale">Rationale</a></li> | 
|---|
 | 27 |         <li><a href="#background">Background</a> | 
|---|
 | 28 |                 <ul> | 
|---|
 | 29 |                         <li><a href="#parameters">CRC Parameters</a></li> | 
|---|
 | 30 |                 </ul></li> | 
|---|
 | 31 |         <li><a href="#crc_basic">Theoretical CRC Computer</a></li> | 
|---|
 | 32 |         <li><a href="#crc_optimal">Optimized CRC Computer</a></li> | 
|---|
 | 33 |         <li><a href="#usage">Computer Usage</a></li> | 
|---|
 | 34 |         <li><a href="#crc_func">CRC Function</a></li> | 
|---|
 | 35 |         <li><a href="#a_crc_func">Augmented-CRC Functions</a></li> | 
|---|
 | 36 |         <li><a href="#crc_ex">Pre-Defined CRC Samples</a></li> | 
|---|
 | 37 |         <li><a href="#references">References</a></li> | 
|---|
 | 38 |         <li><a href="#credits">Credits</a> | 
|---|
 | 39 |                 <ul> | 
|---|
 | 40 |                         <li><a href="#contributors">Contributors</a></li> | 
|---|
 | 41 |                         <li><a href="#acknowledgements">Acknowledgements</a></li> | 
|---|
 | 42 |                         <li><a href="#history">History</a></li> | 
|---|
 | 43 |                 </ul></li> | 
|---|
 | 44 | </ol> | 
|---|
 | 45 |  | 
|---|
 | 46 | <h2><a name="header">Header Synopsis</a></h2> | 
|---|
 | 47 |  | 
|---|
 | 48 | <blockquote><pre>#include <boost/integer.hpp>  <i>// for boost::uint_t</i> | 
|---|
 | 49 | #include <cstddef>            <i>// for std::size_t</i> | 
|---|
 | 50 |  | 
|---|
 | 51 | namespace boost | 
|---|
 | 52 | { | 
|---|
 | 53 |  | 
|---|
 | 54 | template < std::size_t Bits > | 
|---|
 | 55 |     class crc_basic; | 
|---|
 | 56 |  | 
|---|
 | 57 | template < std::size_t Bits, <em>impl_def</em> TruncPoly = 0u, | 
|---|
 | 58 |            <em>impl_def</em> InitRem = 0u, | 
|---|
 | 59 |            <em>impl_def</em> FinalXor = 0u, bool ReflectIn = false, | 
|---|
 | 60 |            bool ReflectRem = false > | 
|---|
 | 61 |     class crc_optimal; | 
|---|
 | 62 |  | 
|---|
 | 63 | template < std::size_t Bits, <em>impl_def</em> TruncPoly, | 
|---|
 | 64 |            <em>impl_def</em> InitRem, <em>impl_def</em> FinalXor, | 
|---|
 | 65 |            bool ReflectIn, bool ReflectRem > | 
|---|
 | 66 |     typename uint_t<Bits>::fast  crc( void const *buffer, | 
|---|
 | 67 |      std::size_t byte_count ); | 
|---|
 | 68 |  | 
|---|
 | 69 | template < std::size_t Bits, <em>impl_def</em> TruncPoly > | 
|---|
 | 70 |     typename uint_t<Bits>::fast  augmented_crc( void const *buffer, | 
|---|
 | 71 |      std::size_t byte_count, | 
|---|
 | 72 |      typename uint_t<Bits>::fast initial_remainder ); | 
|---|
 | 73 |  | 
|---|
 | 74 | template < std::size_t Bits, <em>impl_def</em> TruncPoly > | 
|---|
 | 75 |     typename uint_t<Bits>::fast  augmented_crc( void const *buffer, | 
|---|
 | 76 |      std::size_t byte_count ); | 
|---|
 | 77 |  | 
|---|
 | 78 | typedef crc_optimal<16, 0x8005, 0, 0, true, true>         crc_16_type; | 
|---|
 | 79 | typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false>  crc_ccitt_type; | 
|---|
 | 80 | typedef crc_optimal<16, 0x8408, 0, 0, true, true>         crc_xmodem_type; | 
|---|
 | 81 |  | 
|---|
 | 82 | typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> | 
|---|
 | 83 |   crc_32_type; | 
|---|
 | 84 |  | 
|---|
 | 85 | } | 
|---|
 | 86 | </pre></blockquote> | 
|---|
 | 87 |  | 
|---|
 | 88 | <p>The implementation-defined type <var>impl_def</var> stands for the | 
|---|
 | 89 | quickest-to-manipulate built-in unsigned integral type that can | 
|---|
 | 90 | represent at least <var>Bits</var> bits.</p> | 
|---|
 | 91 |  | 
|---|
 | 92 | <h2><a name="rationale">Rationale</a></h2> | 
|---|
 | 93 |  | 
|---|
 | 94 | <p>A common error detection technique, especially with electronic | 
|---|
 | 95 | communications, is an appended checksum.  The transmitter sends its data | 
|---|
 | 96 | bits, followed by the bits of the checksum.  The checksum is based on | 
|---|
 | 97 | operations done on the data bit stream.  The receiver applies the same | 
|---|
 | 98 | operations on the bits it gets, and then gets the checksum.  If the | 
|---|
 | 99 | computed checksum doesn't match the received checksum, then an error | 
|---|
 | 100 | ocurred in the transmission.  There is the slight chance that the error | 
|---|
 | 101 | is only in the checksum, and an actually-correct data stream is | 
|---|
 | 102 | rejected.  There is also the chance of an error occurring that does not | 
|---|
 | 103 | change the checksum, making that error invisible.  CRC is a common | 
|---|
 | 104 | checksum type, used for error detection for hardware interfaces and | 
|---|
 | 105 | encoding formats.</p> | 
|---|
 | 106 |  | 
|---|
 | 107 | <h2><a name="background">Background</a></h2> | 
|---|
 | 108 |  | 
|---|
 | 109 | <p>CRCs work by computing the remainder of a modulo-2 polynominal | 
|---|
 | 110 | division.  The message is treated as the (binary) coefficents of a long | 
|---|
 | 111 | polynominal for the dividend, with the earlier bits of the message fed | 
|---|
 | 112 | first as the polynominal's highest coefficents.  A particular CRC | 
|---|
 | 113 | algorithm has another polynominal associated with it to be used as the | 
|---|
 | 114 | divisor.  The quotient is ignored.  The remainder of the division | 
|---|
 | 115 | considered the checksum.  However, the division uses modulo-2 rules (no | 
|---|
 | 116 | carries) for the coefficents.</p> | 
|---|
 | 117 |  | 
|---|
 | 118 | <p>See <cite><a href="http://www.ross.net/crc/crcpaper.html">A | 
|---|
 | 119 | Painless Guide to CRC Error Detection Algorithms</a></cite> for complete | 
|---|
 | 120 | information.  A clearer guide is at the <a | 
|---|
 | 121 | href="http://www.netrino.com/Connecting/2000-01/">Easier Said Than | 
|---|
 | 122 | Done</a> web page.</p> | 
|---|
 | 123 |  | 
|---|
 | 124 | <h3><a name="parameters">CRC Parameters</a></h3> | 
|---|
 | 125 |  | 
|---|
 | 126 | <dl> | 
|---|
 | 127 |         <dt>Truncated polynominal | 
|---|
 | 128 |         <dd>The divisor polynominal has a degree one bit larger than the | 
|---|
 | 129 |                 checksum (remainder) size.  That highest bit is always one, so | 
|---|
 | 130 |                 it is ignored when describing a particular CRC type.  Excluding | 
|---|
 | 131 |                 this bit makes the divisor fit in the same data type as the | 
|---|
 | 132 |                 checksum. | 
|---|
 | 133 |  | 
|---|
 | 134 |         <dt>Initial remainder | 
|---|
 | 135 |         <dd>The interim CRC remainder changes as each bit is processed.  | 
|---|
 | 136 |                 Usually, the interim remainder starts at zero, but some CRCs use | 
|---|
 | 137 |                 a different initial value to avoid "blind spots."  A | 
|---|
 | 138 |                 blind spot is when a common sequence of message bits does not | 
|---|
 | 139 |                 change certain interim remainder values. | 
|---|
 | 140 |  | 
|---|
 | 141 |         <dt>Final XOR value | 
|---|
 | 142 |         <dd>A CRC remainder can be combined with a defined value, <i>via</i> | 
|---|
 | 143 |                 a bitwise exclusive-or operation, before being returned to the | 
|---|
 | 144 |                 user.  The value is usually zero, meaning the interim remainder | 
|---|
 | 145 |                 is returned unchanged.  The other common value is an all-ones | 
|---|
 | 146 |                 value, meaning that the bitwise complement of the interim | 
|---|
 | 147 |                 remainder is returned. | 
|---|
 | 148 |  | 
|---|
 | 149 |         <dt>Reflected input | 
|---|
 | 150 |         <dd>A message's bits are usually fed a byte at a time, with the | 
|---|
 | 151 |                 highest bits of the byte treated as the higher bits of the | 
|---|
 | 152 |                 dividend polynominal.  Some CRCs reflect the bits (about the | 
|---|
 | 153 |                 byte's center, so the first and last bits are switched, | 
|---|
 | 154 |                 <i>etc.</i>) before feeding. | 
|---|
 | 155 |  | 
|---|
 | 156 |         <dt>Reflected (remainder) output | 
|---|
 | 157 |         <dd>Some CRCs return the reflection of the interim remainder (taking | 
|---|
 | 158 |                 place <em>before</em> the final XOR value stage). | 
|---|
 | 159 | </dl> | 
|---|
 | 160 |  | 
|---|
 | 161 | <h2><a name="crc_basic">Theoretical CRC Computer</a></h2> | 
|---|
 | 162 |  | 
|---|
 | 163 | <blockquote><pre>template < std::size_t Bits > | 
|---|
 | 164 | class boost::crc_basic | 
|---|
 | 165 | { | 
|---|
 | 166 | public: | 
|---|
 | 167 |     // Type | 
|---|
 | 168 |     typedef <em>implementation_defined</em>  value_type; | 
|---|
 | 169 |  | 
|---|
 | 170 |     // Constant reflecting template parameter | 
|---|
 | 171 |     static  std::size_t const  bit_count = Bits; | 
|---|
 | 172 |  | 
|---|
 | 173 |     // Constructor | 
|---|
 | 174 |     explicit  crc_basic( value_type truncated_polynominal, | 
|---|
 | 175 |                value_type initial_remainder = 0, value_type final_xor_value = 0, | 
|---|
 | 176 |                bool reflect_input = false, bool reflect_remainder = false ); | 
|---|
 | 177 |  | 
|---|
 | 178 |     // Internal Operations | 
|---|
 | 179 |     value_type  get_truncated_polynominal() const; | 
|---|
 | 180 |     value_type  get_initial_remainder() const; | 
|---|
 | 181 |     value_type  get_final_xor_value() const; | 
|---|
 | 182 |     bool        get_reflect_input() const; | 
|---|
 | 183 |     bool        get_reflect_remainder() const; | 
|---|
 | 184 |  | 
|---|
 | 185 |     value_type  get_interim_remainder() const; | 
|---|
 | 186 |     void        reset( value_type new_rem ); | 
|---|
 | 187 |     void        reset(); | 
|---|
 | 188 |  | 
|---|
 | 189 |     // External Operations | 
|---|
 | 190 |     void  process_bit( bool bit ); | 
|---|
 | 191 |     void  process_bits( unsigned char bits, std::size_t bit_count ); | 
|---|
 | 192 |     void  process_byte( unsigned char byte ); | 
|---|
 | 193 |     void  process_block( void const *bytes_begin, void const *bytes_end ); | 
|---|
 | 194 |     void  process_bytes( void const *buffer, std::size_t byte_count ); | 
|---|
 | 195 |  | 
|---|
 | 196 |     value_type  checksum() const; | 
|---|
 | 197 |  | 
|---|
 | 198 | }; | 
|---|
 | 199 | </pre></blockquote> | 
|---|
 | 200 |  | 
|---|
 | 201 | <p>The <code>value_type</code> is the smallest built-in type that can | 
|---|
 | 202 | hold the specified (by <code>Bits</code>) number of bits.  This should | 
|---|
 | 203 | be <code>boost::uint_t<Bits>::least</code>, see the <a | 
|---|
 | 204 | href="../integer/integer.htm">documentation for integer type | 
|---|
 | 205 | selection</a> for details.</p> | 
|---|
 | 206 |  | 
|---|
 | 207 | <p>This implementation is slow since it computes its CRC the same way as | 
|---|
 | 208 | in theory, bit by bit.  No optimizations are performed.  It wastes space | 
|---|
 | 209 | since most of the CRC parameters are specified at run-time as | 
|---|
 | 210 | constructor parameters.</p> | 
|---|
 | 211 |  | 
|---|
 | 212 | <h2><a name="crc_optimal">Optimized CRC Computer</a></h2> | 
|---|
 | 213 |  | 
|---|
 | 214 | <blockquote><pre>template < std::size_t Bits, <em>impl_def</em> TruncPoly, | 
|---|
 | 215 |            <em>impl_def</em> InitRem, <em>impl_def</em> FinalXor, | 
|---|
 | 216 |            bool ReflectIn, bool ReflectRem > | 
|---|
 | 217 | class boost::crc_optimal | 
|---|
 | 218 | { | 
|---|
 | 219 | public: | 
|---|
 | 220 |     // Type | 
|---|
 | 221 |     typedef <em>implementation_defined</em>  value_type; | 
|---|
 | 222 |  | 
|---|
 | 223 |     // Constants reflecting template parameters | 
|---|
 | 224 |     static  std::size_t const  bit_count = Bits; | 
|---|
 | 225 |     static  value_type const   truncated_polynominal = TruncPoly; | 
|---|
 | 226 |     static  value_type const   initial_remainder = InitRem; | 
|---|
 | 227 |     static  value_type const   final_xor_value = FinalXor; | 
|---|
 | 228 |     static  bool const         reflect_input = ReflectIn; | 
|---|
 | 229 |     static  bool const         reflect_remainder = ReflectRem; | 
|---|
 | 230 |  | 
|---|
 | 231 |     // Constructor | 
|---|
 | 232 |     explicit  crc_optimal( value_type init_rem = InitRem ); | 
|---|
 | 233 |  | 
|---|
 | 234 |     // Internal Operations | 
|---|
 | 235 |     value_type  get_truncated_polynominal() const; | 
|---|
 | 236 |     value_type  get_initial_remainder() const; | 
|---|
 | 237 |     value_type  get_final_xor_value() const; | 
|---|
 | 238 |     bool        get_reflect_input() const; | 
|---|
 | 239 |     bool        get_reflect_remainder() const; | 
|---|
 | 240 |  | 
|---|
 | 241 |     value_type  get_interim_remainder() const; | 
|---|
 | 242 |     void        reset( value_type new_rem = InitRem ); | 
|---|
 | 243 |  | 
|---|
 | 244 |     // External Operations | 
|---|
 | 245 |     void  process_byte( unsigned char byte ); | 
|---|
 | 246 |     void  process_block( void const *bytes_begin, void const *bytes_end ); | 
|---|
 | 247 |     void  process_bytes( void const *buffer, std::size_t byte_count ); | 
|---|
 | 248 |  | 
|---|
 | 249 |     value_type  checksum() const; | 
|---|
 | 250 |  | 
|---|
 | 251 |     // Operators | 
|---|
 | 252 |     void        operator ()( unsigned char byte ); | 
|---|
 | 253 |     value_type  operator ()() const; | 
|---|
 | 254 |  | 
|---|
 | 255 | }; | 
|---|
 | 256 | </pre></blockquote> | 
|---|
 | 257 |  | 
|---|
 | 258 | <p>The <code>value_type</code> is the quickest-to-manipulate built-in | 
|---|
 | 259 | type that can hold at least the specified (by <code>Bits</code>) number | 
|---|
 | 260 | of bits.  This should be <code>boost::uint_t<Bits>::fast</code>.  | 
|---|
 | 261 | See the <a href="../integer/integer.htm">integer type selection | 
|---|
 | 262 | documentation</a> for details.  The <code>TruncPoly</code>, | 
|---|
 | 263 | <code>InitRem</code>, and <code>FinalXor</code> template parameters also | 
|---|
 | 264 | are of this type.</p> | 
|---|
 | 265 |  | 
|---|
 | 266 | <p>This implementation is fast since it uses as many optimizations as | 
|---|
 | 267 | practical.  All of the CRC parameters are specified at compile-time as | 
|---|
 | 268 | template parameters.  No individual bits are considered; only whole | 
|---|
 | 269 | bytes are passed.  A table of interim CRC values versus byte values is | 
|---|
 | 270 | pre-computed when the first object using a particular bit size, | 
|---|
 | 271 | truncated polynominal, and input reflection state is processed.</p> | 
|---|
 | 272 |  | 
|---|
 | 273 | <h2><a name="usage">Computer Usage</a></h2> | 
|---|
 | 274 |  | 
|---|
 | 275 | <p>The two class templates have different policies on where the CRC's | 
|---|
 | 276 | parameters go.  Both class templates use the number of bits in the CRC | 
|---|
 | 277 | as the first template parameter.  The theoretical computer class | 
|---|
 | 278 | template has the bit count as its only template parameter, all the other | 
|---|
 | 279 | CRC parameters are entered through the constructor.  The optimized | 
|---|
 | 280 | computer class template obtains all its CRC parameters as template | 
|---|
 | 281 | parameters, and instantiated objects are usually | 
|---|
 | 282 | default-constructed.</p> | 
|---|
 | 283 |  | 
|---|
 | 284 | <p>The CRC parameters can be inspected at run-time with the following | 
|---|
 | 285 | member functions: <code>get_truncated_polynominal</code>, | 
|---|
 | 286 | <code>get_initial_remainder</code>, <code>get_final_xor_value</code>, | 
|---|
 | 287 | <code>get_reflect_input</code>, and <code>get_reflect_remainder</code>.  | 
|---|
 | 288 | The fast computer also provides compile-time constants for its CRC | 
|---|
 | 289 | parameters.</p> | 
|---|
 | 290 |  | 
|---|
 | 291 | <p>The <code>get_interim_remainder</code> member function returns the | 
|---|
 | 292 | internal state of the CRC remainder.  It represents the unreflected | 
|---|
 | 293 | remainder of the last division.  Saving an interim remainder allows the | 
|---|
 | 294 | freezing of CRC processing, as long as the other CRC parameters and the | 
|---|
 | 295 | current position of the bit stream are saved.  Restarting a frozen | 
|---|
 | 296 | stream involves constructing a new computer with the most of the old | 
|---|
 | 297 | computer's parameters.  The only change is to use the frozen remainder | 
|---|
 | 298 | as the new computer's initial remainder.  Then the interrupted bit | 
|---|
 | 299 | stream can be fed as if nothing happened.  The fast CRC computer has a | 
|---|
 | 300 | special constructor that takes one argument, an interim remainder, for | 
|---|
 | 301 | this purpose (overriding the initial remainder CRC parameter).</p> | 
|---|
 | 302 |  | 
|---|
 | 303 | <p>The <code>reset</code> member functions reset the internal state of | 
|---|
 | 304 | the CRC remainder to the given value.  If no value is given, then the | 
|---|
 | 305 | internal remainder is set to the initial remainder value when the object | 
|---|
 | 306 | was created.  The remainder must be unreflected.  When a CRC calculation | 
|---|
 | 307 | is finished, calling <code>reset</code> lets the object be reused for a | 
|---|
 | 308 | new session.</p> | 
|---|
 | 309 |  | 
|---|
 | 310 | <p>After any construction, both CRC computers work the same way.  | 
|---|
 | 311 | Feeding new data to a computer is in a seperate operation(s) from | 
|---|
 | 312 | extracting the current CRC value from the computer.  The following table | 
|---|
 | 313 | lists the feeding and extracting operations.</p> | 
|---|
 | 314 |  | 
|---|
 | 315 | <table cellpadding="5" border="1"> | 
|---|
 | 316 |         <caption>Regular CRC Operations</caption> | 
|---|
 | 317 |         <tr> | 
|---|
 | 318 |                 <th>Operation</th> | 
|---|
 | 319 |                 <th>Description</th> | 
|---|
 | 320 |         </tr> | 
|---|
 | 321 |         <tr> | 
|---|
 | 322 |                 <td><code>void process_bit( bool bit );</code></td> | 
|---|
 | 323 |                 <td>Feeds the single <var>bit</var> to the computer, updating | 
|---|
 | 324 |                         the interim CRC.  It is only defined for the slow CRC | 
|---|
 | 325 |                         computer.</td> | 
|---|
 | 326 |         </tr> | 
|---|
 | 327 |         <tr> | 
|---|
 | 328 |                 <td><code>void process_bits( unsigned char bits, std::size_t | 
|---|
 | 329 |                         bit_count );</code></td> | 
|---|
 | 330 |                 <td>Acts as applying <code>process_bit</code> to the lowest | 
|---|
 | 331 |                         <var>bit_count</var> bits given in <var>bits</var>, most | 
|---|
 | 332 |                         significant relevant bit first.  The results are undefined | 
|---|
 | 333 |                         if <var>bit_count</var> exceeds the number of bits per byte. | 
|---|
 | 334 |                         It is only defined for the slow CRC computer.</td> | 
|---|
 | 335 |         </tr> | 
|---|
 | 336 |         <tr> | 
|---|
 | 337 |                 <td><code>void process_byte( unsigned char byte );</code></td> | 
|---|
 | 338 |                 <td>Acts as applying <code>process_bit</code> to the all the | 
|---|
 | 339 |                         bits in <var>byte</var>.  If reflection is not desired, the | 
|---|
 | 340 |                         bits are fed from the most to least significant.  The bits | 
|---|
 | 341 |                         are fed in the opposite order if reflection is desired.</td> | 
|---|
 | 342 |         </tr> | 
|---|
 | 343 |         <tr> | 
|---|
 | 344 |                 <td><code>void process_block( void const *bytes_begin, void | 
|---|
 | 345 |                         const *bytes_end );</code></td> | 
|---|
 | 346 |                 <td>Acts as applying <code>process_byte</code> to each byte in | 
|---|
 | 347 |                         the given memory block.  This memory block starts at | 
|---|
 | 348 |                         <var>bytes_begin</var> and finishes before | 
|---|
 | 349 |                         <var>bytes_end</var>.  The bytes are processed in that | 
|---|
 | 350 |                         order.</td> | 
|---|
 | 351 |         </tr> | 
|---|
 | 352 |         <tr> | 
|---|
 | 353 |                 <td><code>void  process_bytes( void const *buffer, std::size_t | 
|---|
 | 354 |                         byte_count );</code></td> | 
|---|
 | 355 |                 <td>Acts as applying <code>process_byte</code> to each byte in | 
|---|
 | 356 |                         the given memory block.  This memory block starts at | 
|---|
 | 357 |                         <var>buffer</var> and lasts for <var>byte_count</var> bytes. | 
|---|
 | 358 |                          The bytes are processed in ascending order.</td> | 
|---|
 | 359 |         </tr> | 
|---|
 | 360 |         <tr> | 
|---|
 | 361 |                 <td><code>value_type checksum() const;</code></td> | 
|---|
 | 362 |                 <td>Returns the CRC checksum of the data passed in so far, | 
|---|
 | 363 |                         possibly after applying the remainder-reflection and | 
|---|
 | 364 |                         exclusive-or operations.</td> | 
|---|
 | 365 |         </tr> | 
|---|
 | 366 |         <tr> | 
|---|
 | 367 |                 <td><code>void  operator ()( unsigned char byte );</code></td> | 
|---|
 | 368 |                 <td>Calls <code>process_byte</code>.  This member function lets | 
|---|
 | 369 |                         its object act as a (stateful) function object.  It is only | 
|---|
 | 370 |                         defined for the fast CRC computer.</td> | 
|---|
 | 371 |         </tr> | 
|---|
 | 372 |         <tr> | 
|---|
 | 373 |                 <td><code>value_type  operator ()() const;</code></td> | 
|---|
 | 374 |                 <td>Calls <code>checksum</code>.  This member function lets | 
|---|
 | 375 |                         its object act as a generator function object.  It is only | 
|---|
 | 376 |                         defined for the fast CRC computer.</td> | 
|---|
 | 377 |         </tr> | 
|---|
 | 378 | </table> | 
|---|
 | 379 |  | 
|---|
 | 380 | <p>You can use them like this:</p> | 
|---|
 | 381 |  | 
|---|
 | 382 | <blockquote><pre>#include <boost/crc.hpp>      <i>// for boost::crc_basic, boost::crc_optimal</i> | 
|---|
 | 383 | #include <boost/cstdint.hpp>  <i>// for boost::uint16_t</i> | 
|---|
 | 384 |  | 
|---|
 | 385 | #include <algorithm>  <i>// for std::for_each</i> | 
|---|
 | 386 | #include <cassert>    <i>// for assert</i> | 
|---|
 | 387 | #include <cstddef>    <i>// for std::size_t</i> | 
|---|
 | 388 | #include <iostream>   <i>// for std::cout</i> | 
|---|
 | 389 | #include <ostream>    <i>// for std::endl</i> | 
|---|
 | 390 |  | 
|---|
 | 391 |  | 
|---|
 | 392 | // Main function | 
|---|
 | 393 | int | 
|---|
 | 394 | main () | 
|---|
 | 395 | { | 
|---|
 | 396 |     // This is "123456789" in ASCII | 
|---|
 | 397 |     unsigned char const  data[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, | 
|---|
 | 398 |      0x38, 0x39 }; | 
|---|
 | 399 |     std::size_t const    data_len = sizeof( data ) / sizeof( data[0] ); | 
|---|
 | 400 |  | 
|---|
 | 401 |     // The expected CRC for the given data | 
|---|
 | 402 |     boost::uint16_t const  expected = 0x29B1; | 
|---|
 | 403 |  | 
|---|
 | 404 |     // Simulate CRC-CCITT | 
|---|
 | 405 |     boost::crc_basic<16>  crc_ccitt1( 0x1021, 0xFFFF, 0, false, false ); | 
|---|
 | 406 |     crc_ccitt1.process_bytes( data, data_len ); | 
|---|
 | 407 |     assert( crc_ccitt1.checksum() == expected ); | 
|---|
 | 408 |  | 
|---|
 | 409 |     // Repeat with the optimal version (assuming a 16-bit type exists) | 
|---|
 | 410 |     boost::crc_optimal<16, 0x1021, 0xFFFF, 0, false, false>  crc_ccitt2; | 
|---|
 | 411 |     crc_ccitt2 = std::for_each( data, data + data_len, crc_ccitt2 ); | 
|---|
 | 412 |     assert( crc_ccitt2() == expected ); | 
|---|
 | 413 |  | 
|---|
 | 414 |     std::cout << "All tests passed." << std::endl; | 
|---|
 | 415 |     return 0; | 
|---|
 | 416 | } | 
|---|
 | 417 | </pre></blockquote> | 
|---|
 | 418 |  | 
|---|
 | 419 | <h2><a name="crc_func">CRC Function</a></h2> | 
|---|
 | 420 |  | 
|---|
 | 421 | <blockquote><pre>template < std::size_t Bits, <em>impl_def</em> TruncPoly, | 
|---|
 | 422 |  <em>impl_def</em> InitRem, <em>impl_def</em> FinalXor, | 
|---|
 | 423 |  bool ReflectIn, bool ReflectRem > | 
|---|
 | 424 | typename boost::uint_t<Bits>::fast | 
|---|
 | 425 | boost::crc( void const *buffer, std::size_t byte_count ); | 
|---|
 | 426 | </pre></blockquote> | 
|---|
 | 427 |  | 
|---|
 | 428 | <p>The <code>boost::crc</code> function template computes the CRC of a | 
|---|
 | 429 | given data block.  The data block starts at the address given by | 
|---|
 | 430 | <var>buffer</var> and lasts for <var>byte_count</var> bytes.  The CRC | 
|---|
 | 431 | parameters are passed through template arguments, identical to the | 
|---|
 | 432 | optimized CRC computer (<a href="#crc_optimal">see above</a>).  In fact, | 
|---|
 | 433 | such a computer is used to implement this function.</p> | 
|---|
 | 434 |  | 
|---|
 | 435 | <h2><a name="a_crc_func">Augmented-CRC Functions</a></h2> | 
|---|
 | 436 |  | 
|---|
 | 437 | <blockquote><pre>template < std::size_t Bits, <em>impl_def</em> TruncPoly > | 
|---|
 | 438 | typename boost::uint_t<Bits>::fast | 
|---|
 | 439 | boost::augmented_crc( void const *buffer, std::size_t byte_count, | 
|---|
 | 440 |  typename boost::uint_t<Bits>::fast initial_remainder ); | 
|---|
 | 441 |  | 
|---|
 | 442 | template < std::size_t Bits, <em>impl_def</em> TruncPoly > | 
|---|
 | 443 | typename boost::uint_t<Bits>::fast | 
|---|
 | 444 | boost::augmented_crc( void const *buffer, std::size_t byte_count ); | 
|---|
 | 445 | </pre></blockquote> | 
|---|
 | 446 |  | 
|---|
 | 447 | <p>All the other CRC-computing function or class templates work assuming | 
|---|
 | 448 | that the division steps start immediately on the first message bits.  | 
|---|
 | 449 | The two <code>boost::augmented_crc</code> function templates have a | 
|---|
 | 450 | different division order.  Instead of combining (<i>via</i> bitwise | 
|---|
 | 451 | exclusive-or) the current message bit with the highest bit of a separate | 
|---|
 | 452 | remainder, these templates shift a new message bit into the low bit of a | 
|---|
 | 453 | remainder register as the highest bit is shifted out.  The new method | 
|---|
 | 454 | means that the bits in the inital remainder value are processed before | 
|---|
 | 455 | any of the actual message bits are processed.  To compensate, the real | 
|---|
 | 456 | CRC can only be extracted after feeding enough zero bits (the same count | 
|---|
 | 457 | as the register size) after the message bits.</p> | 
|---|
 | 458 |  | 
|---|
 | 459 | <p>The template parameters of both versions of the function template are | 
|---|
 | 460 | the CRC's bit size (<code>Bits</code>) and the truncated polynominal | 
|---|
 | 461 | (<code>TruncPoly</code>).  The version of the function template that | 
|---|
 | 462 | takes two arguments calls the three-argument version with the | 
|---|
 | 463 | <var>initial_remainder</var> parameter filled as zero.  Both versions | 
|---|
 | 464 | work on the data block starting at the address <var>buffer</var> for | 
|---|
 | 465 | <var>byte_count</var> bytes.</p> | 
|---|
 | 466 |  | 
|---|
 | 467 | <p>These function templates are useful if the bytes of the CRC directly | 
|---|
 | 468 | follow the message's bytes.  First, set the bytes of where the CRC will | 
|---|
 | 469 | go to zero.  Then use <code>augmented_crc</code> over the augmented | 
|---|
 | 470 | message, <i>i.e.</i> the message bytes and the appended CRC bytes.  Then | 
|---|
 | 471 | assign the result to the CRC.  To later check a received message, either | 
|---|
 | 472 | use <code>augmented_crc</code> (with the same parameters as | 
|---|
 | 473 | transmission, of course) on the received <em>unaugmented</em> message | 
|---|
 | 474 | and check if the result equals the CRC, or use | 
|---|
 | 475 | <code>augmented_crc</code> on the received <em>augmented</em> message | 
|---|
 | 476 | and check if the result equals zero.  Note that the CRC has to be stored | 
|---|
 | 477 | with the more-significant bytes first (big-endian).</p> | 
|---|
 | 478 |  | 
|---|
 | 479 | <p>Interruptions in the CRC data can be handled by feeding the result of | 
|---|
 | 480 | <code>augmented_crc</code> of the previous data block as the | 
|---|
 | 481 | <var>initial_remainder</var> when calling <code>augmented_crc</code> on | 
|---|
 | 482 | the next data block.  Remember that the actual CRC can only be | 
|---|
 | 483 | determined after feeding the augmented bytes.  Since this method uses | 
|---|
 | 484 | modulo-2 polynominal division at its most raw, neither final XOR values | 
|---|
 | 485 | nor reflection can be used.</p> | 
|---|
 | 486 |  | 
|---|
 | 487 | <p>Note that for the same CRC system, the initial remainder for | 
|---|
 | 488 | augmented message method will be different than for the unaugmented | 
|---|
 | 489 | message method.  The main exception is zero; if the augmented-CRC | 
|---|
 | 490 | algorithm uses a zero initial remainder, the equivalent unaugmented-CRC | 
|---|
 | 491 | algorithm will also use a zero initial remainder.  Given an initial | 
|---|
 | 492 | remainder for a augmented-CRC algorithm, the result from processing just | 
|---|
 | 493 | zero-valued CRC bytes without any message bytes is the equivalent inital | 
|---|
 | 494 | remainder for the unaugmented-CRC algorithm.  An example follows:</p> | 
|---|
 | 495 |  | 
|---|
 | 496 | <blockquote><pre>#include <boost/crc.hpp>      <i>// for boost::crc_basic, boost::augmented_crc</i> | 
|---|
 | 497 | #include <boost/cstdint.hpp>  <i>// for boost::uint16_t</i> | 
|---|
 | 498 |  | 
|---|
 | 499 | #include <cassert>    <i>// for assert</i> | 
|---|
 | 500 | #include <iostream>   <i>// for std::cout</i> | 
|---|
 | 501 | #include <ostream>    <i>// for std::endl</i> | 
|---|
 | 502 |  | 
|---|
 | 503 |  | 
|---|
 | 504 | // Main function | 
|---|
 | 505 | int | 
|---|
 | 506 | main () | 
|---|
 | 507 | { | 
|---|
 | 508 |     using boost::uint16_t; | 
|---|
 | 509 |     using boost::augmented_crc; | 
|---|
 | 510 |  | 
|---|
 | 511 |     uint16_t        data[6] = { 2, 4, 31, 67, 98, 0 }; | 
|---|
 | 512 |     uint16_t const  init_rem = 0x123; | 
|---|
 | 513 |  | 
|---|
 | 514 |     uint16_t  crc1 = augmented_crc<16, 0x8005>( data, sizeof(data), init_rem ); | 
|---|
 | 515 |  | 
|---|
 | 516 |     uint16_t const  zero = 0; | 
|---|
 | 517 |     uint16_t const  new_init_rem = augmented_crc<16, 0x8005>( &zero, sizeof(zero) ); | 
|---|
 | 518 |  | 
|---|
 | 519 |     boost::crc_basic<16>  crc2( 0x8005, new_init_rem ); | 
|---|
 | 520 |     crc2.process_block( data, &data[5] );  // don't include CRC | 
|---|
 | 521 |     assert( crc2.checksum() == crc1 ); | 
|---|
 | 522 |  | 
|---|
 | 523 |     std::cout << "All tests passed." << std::endl; | 
|---|
 | 524 |     return 0; | 
|---|
 | 525 | } | 
|---|
 | 526 | </pre></blockquote> | 
|---|
 | 527 |  | 
|---|
 | 528 | <h2><a name="crc_ex">Pre-Defined CRC Samples</a></h2> | 
|---|
 | 529 |  | 
|---|
 | 530 | <p>Four sample CRC types are given, representing several common CRC | 
|---|
 | 531 | algorithms.  For example, computations from <code>boost::crc_32_type</code> | 
|---|
 | 532 | can be used for implementing the PKZip standard.  Note that, in general, this | 
|---|
 | 533 | library is concerned with CRC implementation, and not with determining | 
|---|
 | 534 | "good" sets of CRC parameters.</p> | 
|---|
 | 535 |  | 
|---|
 | 536 | <table cellpadding="5" border="1"> | 
|---|
 | 537 |         <caption>Common CRCs</caption> | 
|---|
 | 538 |         <tr> | 
|---|
 | 539 |                 <th>Algorithm</th> | 
|---|
 | 540 |                 <th>Example Protocols</th> | 
|---|
 | 541 |         </tr> | 
|---|
 | 542 |         <tr> | 
|---|
 | 543 |                 <td><code>crc_16_type</code></td> | 
|---|
 | 544 |                 <td>BISYNCH, ARC</td> | 
|---|
 | 545 |         </tr> | 
|---|
 | 546 |         <tr> | 
|---|
 | 547 |                 <td><code>crc_ccitt_type</code></td> | 
|---|
 | 548 |                 <td>designated by CCITT (Comité Consultatif International | 
|---|
 | 549 |                     Télégraphique et Téléphonique)</td> | 
|---|
 | 550 |         </tr> | 
|---|
 | 551 |         <tr> | 
|---|
 | 552 |                 <td><code>crc_xmodem_type</code></td> | 
|---|
 | 553 |                 <td>XMODEM</td> | 
|---|
 | 554 |         </tr> | 
|---|
 | 555 |         <tr> | 
|---|
 | 556 |                 <td><code>crc_32_type</code></td> | 
|---|
 | 557 |                 <td>PKZip, AUTODIN II, Ethernet, FDDI</td> | 
|---|
 | 558 |         </tr> | 
|---|
 | 559 | </table> | 
|---|
 | 560 |  | 
|---|
 | 561 | <hr> | 
|---|
 | 562 |  | 
|---|
 | 563 | <h2><a name="references">References</a></h2> | 
|---|
 | 564 |  | 
|---|
 | 565 | <ul> | 
|---|
 | 566 |         <li>The CRC header itself: <cite><a href="../../boost/crc.hpp">crc.hpp</a></cite> | 
|---|
 | 567 |         <li>Some test code: <cite><a href="crc_test.cpp">crc_test.cpp</a></cite> | 
|---|
 | 568 |         <li>Some example code: <cite><a href="crc_example.cpp">crc_example.cpp</a></cite> | 
|---|
 | 569 | </ul> | 
|---|
 | 570 |  | 
|---|
 | 571 | <h2><a name="credits">Credits</a></h2> | 
|---|
 | 572 |  | 
|---|
 | 573 | <h3><a name="contributors">Contributors</a></h3> | 
|---|
 | 574 |  | 
|---|
 | 575 | <dl> | 
|---|
 | 576 |         <dt>Michael Barr (<a | 
|---|
 | 577 |                 href="mailto:mbarr@netrino.com">mbarr@netrino.com</a>) | 
|---|
 | 578 |         <dd>Wrote <a | 
|---|
 | 579 |                 href="http://www.netrino.com/Connecting/2000-01/">Easier Said | 
|---|
 | 580 |                 Than Done</a>, a less-confusing guide to implementing CRC | 
|---|
 | 581 |                 algorithms.  (Originally published as "Slow and Steady | 
|---|
 | 582 |                 Never Lost the Race" in the January 2000 issue of <cite><a | 
|---|
 | 583 |                 href="http://www.embedded.com/">Embedded Systems | 
|---|
 | 584 |                 Programming</a></cite>, pages 37–46.) | 
|---|
 | 585 |  | 
|---|
 | 586 |         <dt>Daryle Walker | 
|---|
 | 587 |         <dd>Started the library and contributed the theoretical and optimal | 
|---|
 | 588 |                 CRC computation class templates and the CRC computing function | 
|---|
 | 589 |                 template.  Contributed <cite><a | 
|---|
 | 590 |                 href="crc_test.cpp">crc_test.cpp</a></cite> and <cite><a | 
|---|
 | 591 |                 href="crc_example.cpp">crc_example.cpp</a></cite>. | 
|---|
 | 592 |  | 
|---|
 | 593 |         <dt>Ross N. Williams | 
|---|
 | 594 |         <dd>Wrote <cite><a href="http://www.ross.net/crc/crcpaper.html">A | 
|---|
 | 595 |                 Painless Guide to CRC Error Detection Algorithms</a></cite>, a | 
|---|
 | 596 |                 definitive source of CRC information. | 
|---|
 | 597 | </dl> | 
|---|
 | 598 |  | 
|---|
 | 599 | <h3><a name="acknowledgements">Acknowledgements</a></h3> | 
|---|
 | 600 |  | 
|---|
 | 601 | <p>For giving advice on compiler/C++ compliance, implementation, | 
|---|
 | 602 | interface, algorithms, and bug reports:</p> | 
|---|
 | 603 |  | 
|---|
 | 604 | <ul> | 
|---|
 | 605 |         <li>Darin Adler</li> | 
|---|
 | 606 |         <li>Beman Dawes</li> | 
|---|
 | 607 |         <li>Doug Gregor</li> | 
|---|
 | 608 |         <li>John Maddock</li> | 
|---|
 | 609 |         <li>Joe Mariadassou</li> | 
|---|
 | 610 |         <li>Jens Maurer</li> | 
|---|
 | 611 |         <li>Vladimir Prus</li> | 
|---|
 | 612 |         <li>Joel Young</li> | 
|---|
 | 613 | </ul> | 
|---|
 | 614 |  | 
|---|
 | 615 | <h3><a name="history">History</a></h3> | 
|---|
 | 616 |  | 
|---|
 | 617 | <dl> | 
|---|
 | 618 |         <dt>15 Jun 2003, Daryle Walker | 
|---|
 | 619 |         <dd>Added example program. | 
|---|
 | 620 |  | 
|---|
 | 621 |         <dt>14 May 2001, Daryle Walker | 
|---|
 | 622 |         <dd>Initial version. | 
|---|
 | 623 | </dl> | 
|---|
 | 624 |  | 
|---|
 | 625 | <hr> | 
|---|
 | 626 |  | 
|---|
 | 627 | <p>Revised: 15 June 2003</p> | 
|---|
 | 628 |  | 
|---|
 | 629 | <p>Copyright 2001, 2003 Daryle Walker.  Use, modification, and distribution | 
|---|
 | 630 | are subject to the Boost Software License, Version 1.0.  (See accompanying | 
|---|
 | 631 | file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at | 
|---|
 | 632 | <<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p> | 
|---|
 | 633 |  | 
|---|
 | 634 | </body> | 
|---|
 | 635 | </html> | 
|---|