| 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> |
|---|