Blame view

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