crc.qbk 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. [library Boost.CRC
  2. [quickbook 1.5]
  3. [version 1.5]
  4. [id crc]
  5. [dirname crc]
  6. [copyright 2001 2003 2012 Daryle Walker]
  7. [purpose Cyclic Redundancy Code computation]
  8. [category Miscellaneous]
  9. [authors [Walker, Daryle]]
  10. [license
  11. Distributed under the Boost Software License, Version 1.0.
  12. (See the accompanying file LICENSE_1_0.txt or a copy at
  13. [@http://www.boost.org/LICENSE_1_0.txt])
  14. ]
  15. [source-mode c++]
  16. ]
  17. [/ Macros ]
  18. [def __RMCA__ Rocksoft\u2122 Model CRC Algorithm]
  19. [section:motivation What is Boost.CRC?]
  20. CRCs (cyclic redundancy codes) is one common technique to confirming data
  21. integrity after transmission. The [*Boost.CRC] library provides access to two
  22. styles of CRC computation, one as a function template, the other as a function
  23. template and two computation object class templates, where the two class
  24. templates differ in speed.
  25. [endsect]
  26. [section:introduction Introduction]
  27. [note
  28. Some of the introductory material is based on
  29. [@http://www.ross.net/crc/download/crc_v3.txt ['A Painless Guide to CRC
  30. Error Detection Algorithms]] by Ross N. Williams at his
  31. [@http://www.ross.net/crc/ [*The CRC Pitstop]] site.
  32. ]
  33. When binary data is transmitted, usually electronically, there is a chance that
  34. the data gets corrupted. One method to pick up said corruption is to generate
  35. some value that is coded from the original data, send said value to the
  36. receiver, then confirm that the received data generates the same value when it's
  37. coded at the destination.
  38. There are several possibilities after the receiver's check:
  39. * The check value matches at both places and the data was transmitted intact.
  40. * The data got corrupted and the check values do not match.
  41. * The data is intact, but the check value got corrupted. This can't the
  42. distinguished from the previous case, but is a (relatively) safe false
  43. positive.
  44. * Either the data and/or check value gets corrupted, but such that the results
  45. of the check-coding are still consistent. This is a dangerous false negative!
  46. The way to minimize false negatives is to choose coding algorithms that cause a
  47. lot of churn per input, especially a variable amount.
  48. The check values are known as [*checksum]s because they are used to /check/ for
  49. data consistency and the first coding algorithms were addition- (i.e.
  50. ['sum]ming-) based.
  51. [section:intro_crcs CRCs]
  52. [*Cyclic Redundancy Codes] are a type of consistency check that treats the
  53. message data as a (long) dividend of a modulo-2 polynomial division. Modulo-2
  54. arithmetic doesn't use carries/borrows when combining numbers. A specific CRC
  55. defines a set number of bits to work on at a time, where said number is also the
  56. degree of a fixed polynomial (with modulo-2 coefficients) used as a divisor.
  57. Since ordering doesn't apply to modulo arithmetic, the check between the current
  58. high part of the dividend and the trial partial product (of the divisor and the
  59. trial new quotient coefficient) is done by seeing if the highest-degree
  60. coefficient of the dividend is one. (The highest-degree coefficient of the
  61. divisor must be one by definition, since it's the only non-zero choice.) The
  62. remainder after the division is finished is used as the basis of the CRC
  63. checksum.
  64. [section:intro_crcs_impl CRC Implementation]
  65. For a given degree /x/ for the modulo-2 polynomial divisor, the remainder will
  66. have at most /x/ terms (from degree /x/ - 1 down to the constant term). The
  67. coefficients are modulo-2, which means that they can be represented by 0's and
  68. 1's. So a remainder can be modeled by an (unsigned) integer of at least /x/
  69. bits in *width*.
  70. The divisor must have its /x/ degree term be one, which means it is always known
  71. and can be implied instead of having to explicitly include in representations.
  72. Its lower /x/ terms must be specified, so a divisor can be modeled the same way
  73. as remainders. With such a modeling, the divisor representation could be said
  74. to be truncated since the uppermost term's value is implied and not stored.
  75. The remainder and [*(truncated) divisor polynomial]s are stored as basic
  76. computer integers. This is in contrast to the dividend, which is modeled from
  77. the input stream of data bits, where each new incoming bit is the next lower
  78. term of the dividend polynomial. Long division can be processed in piecemeal,
  79. reading new upper terms as needed. This maps to reading the data a byte (or
  80. bit) at a time, generating updated remainders just-in-time, without needing to
  81. read (and/or store(!)) the entire data message at once.
  82. Long division involves appending new dividend terms after the previous terms
  83. have been processed into the (interim) remainder. So the remainder it the only
  84. thing that has to change during each division step; a new input byte (or bit) is
  85. combined with the remainder to make the interim dividend, and then combined with
  86. the partial product (based on the divisor and top dividend bit(s)) to become a
  87. remainder again.
  88. [endsect]
  89. [section:intro_crcs_augment Message Augmentation]
  90. When all of the input data has been read during division, the last /x/ bits are
  91. still stuck in the interim remainder. They have not been pushed through the
  92. division steps; to do so, /x/ zero-valued extra bits must be passed into the
  93. system. This ensures all of the message's data bits get processed. The
  94. post-processed remainder is the checksum. The system requires the message to be
  95. *augmented* with /x/ extra bits to get results.
  96. Alternatively, if the post-division augmentation bits are the expected checksum
  97. instead, then the remainder will "subtract" the checksum with itself, giving
  98. zero as the final remainder. The remainder will end up non-zero if bit errors
  99. exist in either the data or checksum or both. This option requires the checksum
  100. to be fed from highest-order bit first on down (i.e. big endian).
  101. Exploiting the properties of how the division is carried out, the steps can be
  102. rearranged such that the post-processing zero-valued bits are not needed; their
  103. effect is merged into the start of the process. Such systems read *unaugmented*
  104. messages and expose the checksum directly from the interim remainder afterwards.
  105. (You can't use the "augment-message-with-checksum-and-zero-check" technique with
  106. this, of course.)
  107. [endsect]
  108. [section:intro_crcs_param Other CRC Parameters]
  109. Since long division proceeds from the uppermost terms on down, it's easiest to
  110. treat an incoming byte as the uppermost unprocessed terms, and to read the bits
  111. within that byte as the highest-order bit is the uppermost unprocessed term and
  112. go down. However, some hardware implementations have an easier time reading
  113. each byte from the lowest-order bit and go up. To simulate those systems in
  114. software, the program needs to be flagged that *input reflection* needs to be
  115. applied. Reflecting a built-in integer reverses the order of its bits, such
  116. that the lowest- and highest-order bits swap states, the next-lowest- and
  117. next-highest-order bits swap, etc. The input reflection can be done by
  118. reflecting each byte as it comes in or keeping the bytes unchanged but reflect
  119. the other internal functioning. The latter sounds harder, but what it usually
  120. done in the real world, since it's a one-time cost, unlike reflecting the bytes.
  121. Similarly, the final remainder is processed by some hardware in reverse order,
  122. which means software that simulate such systems need to flag that *output
  123. reflection* is in effect.
  124. Some CRCs don't return the remainder directly (reflected or not), but add an
  125. extra step complementing the output bits. Complementing turns 1 values into 0
  126. values and vice versa. This can simulated by using a XOR (exclusive-or) bit
  127. mask of all 1-values (of the same bit length as the remainder). Some systems
  128. use a *final XOR mask* that isn't all 1-values, for variety. (This mask takes
  129. place /after/ any output reflection.)
  130. At the other end, the built-in-integer register normally starts at zero as the
  131. first bytes are read. Instead of just doing nothing but load input bits for /x/
  132. steps, some CRC systems use a non-zero *initial remainder* to add extra
  133. processing. This initial value has to be different for the augmented versus
  134. un-augmented versions of the same system, due to possible incorporation with the
  135. zero-valued augment bits.
  136. [endsect]
  137. [section:intro_crcs_rmca Compact CRC Parameter Specification]
  138. The __RMCA__, or RMCA for short, was designed by Ross Williams to describe all
  139. the specification points of a given CRC system (quoted):
  140. [variablelist RMCA Parameters
  141. [[WIDTH] [This is the width of the algorithm expressed in bits. This
  142. is one less than the width of the Poly.]]
  143. [[POLY] [This parameter is the poly. This is a binary value that
  144. should be specified as a hexadecimal number. The top bit of the
  145. poly should be omitted. For example, if the poly is 10110, you
  146. should specify 06. An important aspect of this parameter is that it
  147. represents the unreflected poly; the bottom bit of this parameter
  148. is always the LSB of the divisor during the division regardless of
  149. whether the algorithm being modelled is reflected.]]
  150. [[INIT] [This parameter specifies the initial value of the register
  151. when the algorithm starts. This is the value that is to be assigned
  152. to the register in the direct table algorithm. In the table
  153. algorithm, we may think of the register always commencing with the
  154. value zero, and this value being XORed into the register after the
  155. N'th bit iteration. This parameter should be specified as a
  156. hexadecimal number.]]
  157. [[REFIN] [This is a boolean parameter. If it is FALSE, input bytes are
  158. processed with bit 7 being treated as the most significant bit
  159. (MSB) and bit 0 being treated as the least significant bit. If this
  160. parameter is FALSE, each byte is reflected before being processed.]]
  161. [[REFOUT] [This is a boolean parameter. If it is set to FALSE, the
  162. final value in the register is fed into the XOROUT stage directly,
  163. otherwise, if this parameter is TRUE, the final register value is
  164. reflected first.]]
  165. [[XOROUT] [This is an W-bit value that should be specified as a
  166. hexadecimal number. It is XORed to the final register value (after
  167. the REFOUT) stage before the value is returned as the official
  168. checksum.]]
  169. ]
  170. His description assumes an octet-sized byte. The /POLY/ is the (truncated)
  171. divisor. The /INIT/ is the initial remainder, assuming the unaugmented version
  172. of CRC processing is used. (If you're using an augmented-style CRC, you have to
  173. undo the effect of the built-in zero-augment before initialization.)
  174. [endsect]
  175. The two function templates and two class templates in this library provide ways
  176. to carry out CRC computations. You give the various __RMCA__ parameters as
  177. template parameters and/or constructor parameters. You then submit all the
  178. message data bytes at once (for the functions) or piecemeal (for the class
  179. objects).
  180. [endsect]
  181. Note that some error-detection techniques merge their checksum results within
  182. the message data, while CRC checksums are either at the end (when augmented,
  183. without either kind of reflection, with a bit-width that's a multiple of byte
  184. size, and no XOR mask) or out-of-band.
  185. [endsect]
  186. [section:crc_basic Theoretical CRC Computer]
  187. #include <cstddef> // for std::size_t
  188. namespace boost
  189. {
  190. template < std::size_t Bits >
  191. class crc_basic;
  192. }
  193. The [*`boost::crc_basic`] class template acts as an unaugmented-CRC processor
  194. that can accept input at the bit-level. It only takes one __RMCA__ parameter as
  195. a template parameter, the /WIDTH/, which determines the built-in unsigned integer
  196. type used for division registers. The other __RMCA__ parameters can be passed
  197. on through the constructor. (Most of the parameters have defaults.)
  198. The integer type used for registers is published as `value_type`, while the
  199. __RMCA__ attributes can be discovered as:
  200. [table:crc_basic_rmca RMCA Parameters in boost::crc_basic
  201. [[Parameter] [Member Name] [Kind] [Expression Type]]
  202. [[['WIDTH]] [`bit_count`] [class-static immutable data member] [`std::size_t`]]
  203. [[['POLY]] [`get_truncated_polynominal`] [`const` member function] [`value_type`]]
  204. [[['INIT]] [`get_initial_remainder`] [`const` member function] [`value_type`]]
  205. [[['REFIN]] [`get_reflect_input`] [`const` member function] [`bool`]]
  206. [[['REFOUT]] [`get_reflect_remainder`] [`const` member function] [`bool`]]
  207. [[['XOROUT]] [`get_final_xor_value`] [`const` member function] [`value_type`]]
  208. ]
  209. Since most of the parameters are specified at run-time, you can reuse a single
  210. computer object for separate runs with differing parameters. The type uses the
  211. automatically-defined copy/move/assign and destruction routines.
  212. [import ./crc_examples.cpp]
  213. [crc_basic_reuse]
  214. This example necessarily demonstrates input and output. There is one output
  215. member function, `checksum` that returns the remainder from the CRC steps plus
  216. any post-processing reflection and/or XOR-masking. There are several options
  217. to submit input data for processing:
  218. [table:crc_basic_input Member Functions for Input in boost::crc_basic
  219. [[Member Function] [Input Type/Style]]
  220. [[`process_bit`] [A single bit.]]
  221. [[`process_bits`] [A specified number of bits within the given byte.
  222. Reading starts from the highest-order desired bit.]]
  223. [[`process_byte`] [An entire byte. The bits within the byte are read in an
  224. order consistent with `get_reflect_input`.]]
  225. [[`process_block`] [All bytes in the range. The range is defined by a
  226. pointer to the first byte and another pointer to one (byte) past-the-end.]]
  227. [[`process_bytes`] [All bytes in the range. The range is defined by a
  228. pointer to the first byte and a count of number of bytes to read.]]
  229. ]
  230. The input functions currently do not return anything.
  231. [crc_piecemeal_run]
  232. The input-influenced state of a computer object may be read with the
  233. `get_interim_remainder` member function. An object may be loaded with the same
  234. kind of state with the one-argument version of the `reset` member function.
  235. The state is the remainder from the CRC operations performed on all the
  236. already-entered input, without any output post-processing.
  237. The two functions can be used together to save the state to a persistent medium
  238. and restore it later. Note that the __RMCA__ parameters have to saved/restored
  239. via other means, if they're not fixed within a program.
  240. Calling `reset` with no arguments sets the interim remainder to what /INIT/ was
  241. set at object construction. This lets one computer object be used for
  242. independent runs with separate data messages using the same CRC standard.
  243. [endsect]
  244. [section:crc_optimal Optimized CRC Computer]
  245. #include <boost/cstdint.hpp> // for boost::uintmax_t
  246. #include <cstddef> // for std::size_t
  247. namespace boost
  248. {
  249. template < std::size_t Bits, uintmax_t TruncPoly, uintmax_t InitRem,
  250. uintmax_t FinalXor, bool ReflectIn, bool ReflectRem >
  251. class crc_optimal;
  252. }
  253. The [*`boost::crc_optimal`] class template acts as an unaugmented-CRC processor
  254. that can accept input at the byte-level. It takes all the __RMCA__ parameters
  255. as template parameters. Like in `crc_basic`, the /WIDTH/ stays as the first
  256. parameter and determines the built-in unsigned integer type used for division
  257. registers. The other __RMCA__ parameters move up to the template parameter
  258. field in the same relative order they were in the `crc_basic` constructor.
  259. (Some parameters have defaults.) Objects based from `crc_optimal` can either be
  260. default-constructed, giving it the same behavior as a `crc_basic` object with
  261. the equivalent settings, or use one parameter, which overrides the initial
  262. remainder value[footnote i.e. The interim-remainder before any input is read.]
  263. without permanently affecting the initial-remainder attribute.
  264. Besides template parameters and construction, `crc_optimal` differs from
  265. `crc_basic` interface-wise by:
  266. * Adding five class-static immutable data members corresponding to the new
  267. template parameters.
  268. [table:crc_optimal_rmca Additional RMCA Expressions in boost::crc_optimal
  269. [[New Member] [Equivalent]]
  270. [[`truncated_polynominal`] [`get_truncated_polynominal`]]
  271. [[`initial_remainder`] [`get_initial_remainder`]]
  272. [[`reflect_input`] [`get_reflect_input`]]
  273. [[`reflect_remainder`] [`get_reflect_remainder`]]
  274. [[`final_xor_value`] [`get_final_xor_value`]]
  275. ]
  276. * Removing the `process_bit` and `process_bits` member functions.
  277. * Adding two versions of the `operator ()` member function. The single-argument
  278. version forwards to `process_byte`, making it suitable to STL algorithms that
  279. take (and possibly return) function objects[footnote Like `std::for_each`.].
  280. The argument-less version forwards to `checksum`, making it suitable for STL
  281. algorithms that expect generator objects[footnote Albeit this object won't
  282. change its return value within code that only uses it as a generator.].
  283. * Merging the two `reset` member functions into one. (It uses a single
  284. parameter that can have a default argument).
  285. The major difference between `crc_basic` and `crc_optimal` is the internals.
  286. Objects from `crc_basic` run their CRC algorithm one bit at a time, no matter
  287. which unit is used as input. Objects from `crc_optimal`, when /WIDTH/ is at
  288. least `CHAR_BIT`[footnote i.e. The optimizations are suspended if the /WIDTH/
  289. only justifies using part of a single byte.], use a byte-indexed table-driven CRC
  290. algorithm which is a *lot* faster than processing individual bits.
  291. Since all of the parameters are specified at compile-time, you cannot reuse a
  292. single computer object for separate runs with differing parameters. The type
  293. uses the automatically-defined copy/move/assign and destruction routines.
  294. [endsect]
  295. [section:crc_function CRC Function]
  296. #include <boost/cstdint.hpp> // for boost::uintmax_t
  297. #include <boost/integer.hpp> // for boost::uint_t
  298. #include <cstddef> // for std::size_t
  299. namespace boost
  300. {
  301. template < std::size_t Bits, uintmax_t TruncPoly, uintmax_t InitRem,
  302. uintmax_t FinalXor, bool ReflectIn, bool ReflectRem >
  303. typename uint_t<Bits>::fast crc( void const *buffer, std::size_t
  304. byte_count );
  305. }
  306. The [*`boost::crc`] function template computes the unaugmented CRC of a single
  307. data block in one pass. It has the same template parameter list as
  308. `boost::crc_optimal`, which it uses for implementation. This function saves you
  309. the trouble of setting up and using the `boost::crc_optimal` object manually.
  310. [endsect]
  311. [section:acrc_function Augmented-CRC Function]
  312. #include <boost/cstdint.hpp> // for boost::uintmax_t
  313. #include <boost/integer.hpp> // for boost::uint_t
  314. #include <cstddef> // for std::size_t
  315. namespace boost
  316. {
  317. template < std::size_t Bits, uintmax_t TruncPoly >
  318. typename uint_t<Bits>::fast augmented_crc( void const *buffer,
  319. std::size_t byte_count, typename uint_t<Bits>::fast initial_remainder
  320. = 0u );
  321. }
  322. The [*`boost::augmented_crc`] function computes the augmented-style CRC of a
  323. data block. Like `boost::crc`, the first two template parameters are the
  324. /WIDTH/ and /POLY/. However, the /INIT/ has moved to being a function
  325. parameter, after the data block's starting address and byte length, defaulting
  326. to zero if not given.
  327. This function uses modulo-2 division at its most raw, and so forfeits the
  328. /REFIN/, /REFOUT/, and /XOROUT/ attributes, setting them to `0` or `false`.
  329. Another difference from `boost::crc` is that a non-zero /INIT/ has to be skewed
  330. when used with this function. (No conversion functions are currently given.)
  331. [acrc_piecemeal_run]
  332. Since `augmented_crc` doesn't know when your data ends, you must supply the
  333. augment, either /WIDTH/ zero bits or the expected checksum. The augment can be
  334. either at the end of last data block or from an extra call. Remember that if an
  335. expected checksum is used as the augment, its bits must be arranged in
  336. big-endian order. Because `augmented_crc` reads byte-wise, while augments
  337. assume bit-wise reading, augmentations are valid only when /WIDTH/ is a multiple
  338. of the bits-per-byte ratio (`CHAR_BIT`).
  339. [endsect]
  340. [section:crc_samples Pre-Defined CRC Samples]
  341. namespace boost
  342. {
  343. typedef crc_optimal<16, 0x8005, 0, 0, true, true>
  344. crc_16_type;
  345. typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false>
  346. crc_ccitt_false_t, crc_ccitt_type;
  347. typedef crc_optimal<16, 0x1021, 0, 0, true, true> crc_ccitt_true_t;
  348. typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type;
  349. typedef crc_optimal<16, 0x1021, 0, 0, false, false> crc_xmodem_t;
  350. typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
  351. crc_32_type;
  352. }
  353. Several sample CRC types are given, representing common CRC algorithms. The
  354. samples have now been checked against the
  355. [@http://regregex.bbcmicro.net/crc-catalogue.htm ['Catalogue of parametrised CRC
  356. algorithms]], leading to some new type-aliases corresponding to the corrected
  357. profiles. (Older, incorrect profiles keep their name for backwards
  358. compatibility.) However, this library is primarily concerned with CRC
  359. implementation, and not with determining "good" sets of CRC parameters.
  360. [table:crc_samples_list Common CRCs
  361. [[Computer Type] [Standard(s)]]
  362. [[`crc_16_type`] [BISYNCH, ARC, LHA, ZOO]]
  363. [[`crc_ccitt_false_t`] [Commonly misidentified as the standard by CCITT]]
  364. [[`crc_ccitt_type`] [`crc_ccitt_false_t` (I made the same mistake.)]]
  365. [[`crc_ccitt_true_t`] [Designated by CCITT (Comit\u00E9 Consultatif
  366. International T\u00E9l\u00E9graphique et T\u00E9l\u00E9phonique), KERMIT]]
  367. [[`crc_xmodem_type`] [A mistake I didn't catch in defining
  368. `crc_xmodem_t`.]]
  369. [[`crc_xmodem_t`] [XMODEM, ZMODEM, ACORN]]
  370. [[`crc_32_type`] [ADCCP, PKZip, libPNG, AUTODIN II, Ethernet, FDDI]]
  371. ]
  372. [endsect]
  373. [section:end End Matter]
  374. [heading References]
  375. *The [@boost:/boost/crc.hpp CRC header] itself
  376. *Some [@boost:/libs/crc/test/crc_test.cpp test code] and some
  377. [@boost:/libs/crc/test/crc_test2.cpp newer tests] that use the
  378. [@boost:/libs/test/index.html Boost test library]
  379. *Some [@boost:/libs/crc/crc_example.cpp example code]
  380. [variablelist History
  381. [[Boost 1.49.0] [Refined implementation, testing, and documentation. Some
  382. interfaces were tweaked.]]
  383. [[Boost 1.30.2 (estimated)] [Released an example program.]]
  384. [[Boost 1.22.0] [First public release.]]
  385. ]
  386. [heading Acknowledgments]
  387. For giving advice on compiler/C++ compliance, implementation, interface,
  388. algorithms, and bug reports:
  389. *Darin Adler
  390. *Beman Dawes
  391. *Doug Gregor
  392. *John Maddock
  393. *Joe Mariadassou
  394. *Jens Maurer
  395. *Vladimir Prus
  396. *Joel Young
  397. [variablelist Contributors
  398. [[Michael Barr [@mailto:mbarr@netrino.com mbarr@netrino.com]]
  399. [Wrote
  400. [@http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
  401. ["CRC Implementation Code in C]], a less-confusing guide to implementing
  402. CRC algorithms. (Originally published as ["Slow and Steady Never Lost the
  403. Race] in the January 2000 issue of [@http://www.embedded.com ['Embedded
  404. Systems Programming]], pages 37\u201346. The web version used to be known
  405. as [@http://www.netrino.com/Connecting/2000-01/ ['Easier Said Than Done]].)
  406. ]]
  407. [[Daryle Walker]
  408. [Started the library and contributed the theoretical and optimal CRC
  409. computation class templates and the CRC computing function template.
  410. Contributed the test and example code.
  411. ]]
  412. [[Ross N. Williams]
  413. [Wrote [@http://www.ross.net/crc/crcpaper.html ['A Painless Guide to CRC
  414. Error Detection Algorithms]], a definitive source of CRC information.
  415. ]]
  416. ]
  417. [endsect]
  418. [xinclude autodoc.xml]