Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/crc/crc.html @ 33

Last change on this file since 33 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 24.8 KB
Line 
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)"
11align="middle" width="277" height="86">Header <cite>&lt;<a
12href="../../boost/crc.hpp">boost/crc.hpp</a>&gt;</cite></h1>
13
14<p>The header <cite>&lt;<a
15href="../../boost/crc.hpp">boost/crc.hpp</a>&gt;</cite> supplies two
16class templates in namespace <code>boost</code>.  These templates define
17objects that can compute the <dfn>CRC</dfn>, or cyclic redundancy code
18(or check), of a given stream of data.  The header also supplies
19function 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 &lt;boost/integer.hpp&gt;  <i>// for boost::uint_t</i>
49#include &lt;cstddef&gt;            <i>// for std::size_t</i>
50
51namespace boost
52{
53
54template &lt; std::size_t Bits &gt;
55    class crc_basic;
56
57template &lt; 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 &gt;
61    class crc_optimal;
62
63template &lt; 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 &gt;
66    typename uint_t&lt;Bits&gt;::fast  crc( void const *buffer,
67     std::size_t byte_count );
68
69template &lt; std::size_t Bits, <em>impl_def</em> TruncPoly &gt;
70    typename uint_t&lt;Bits&gt;::fast  augmented_crc( void const *buffer,
71     std::size_t byte_count,
72     typename uint_t&lt;Bits&gt;::fast initial_remainder );
73
74template &lt; std::size_t Bits, <em>impl_def</em> TruncPoly &gt;
75    typename uint_t&lt;Bits&gt;::fast  augmented_crc( void const *buffer,
76     std::size_t byte_count );
77
78typedef crc_optimal&lt;16, 0x8005, 0, 0, true, true&gt;         crc_16_type;
79typedef crc_optimal&lt;16, 0x1021, 0xFFFF, 0, false, false&gt;  crc_ccitt_type;
80typedef crc_optimal&lt;16, 0x8408, 0, 0, true, true&gt;         crc_xmodem_type;
81
82typedef crc_optimal&lt;32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true&gt;
83  crc_32_type;
84
85}
86</pre></blockquote>
87
88<p>The implementation-defined type <var>impl_def</var> stands for the
89quickest-to-manipulate built-in unsigned integral type that can
90represent 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
95communications, is an appended checksum.  The transmitter sends its data
96bits, followed by the bits of the checksum.  The checksum is based on
97operations done on the data bit stream.  The receiver applies the same
98operations on the bits it gets, and then gets the checksum.  If the
99computed checksum doesn't match the received checksum, then an error
100ocurred in the transmission.  There is the slight chance that the error
101is only in the checksum, and an actually-correct data stream is
102rejected.  There is also the chance of an error occurring that does not
103change the checksum, making that error invisible.  CRC is a common
104checksum type, used for error detection for hardware interfaces and
105encoding 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
110division.  The message is treated as the (binary) coefficents of a long
111polynominal for the dividend, with the earlier bits of the message fed
112first as the polynominal's highest coefficents.  A particular CRC
113algorithm has another polynominal associated with it to be used as the
114divisor.  The quotient is ignored.  The remainder of the division
115considered the checksum.  However, the division uses modulo-2 rules (no
116carries) for the coefficents.</p>
117
118<p>See <cite><a href="http://www.ross.net/crc/crcpaper.html">A
119Painless Guide to CRC Error Detection Algorithms</a></cite> for complete
120information.  A clearer guide is at the <a
121href="http://www.netrino.com/Connecting/2000-01/">Easier Said Than
122Done</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 &quot;blind spots.&quot;  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 &lt; std::size_t Bits &gt;
164class boost::crc_basic
165{
166public:
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
202hold the specified (by <code>Bits</code>) number of bits.  This should
203be <code>boost::uint_t&lt;Bits&gt;::least</code>, see the <a
204href="../integer/integer.htm">documentation for integer type
205selection</a> for details.</p>
206
207<p>This implementation is slow since it computes its CRC the same way as
208in theory, bit by bit.  No optimizations are performed.  It wastes space
209since most of the CRC parameters are specified at run-time as
210constructor parameters.</p>
211
212<h2><a name="crc_optimal">Optimized CRC Computer</a></h2>
213
214<blockquote><pre>template &lt; 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 &gt;
217class boost::crc_optimal
218{
219public:
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
259type that can hold at least the specified (by <code>Bits</code>) number
260of bits.  This should be <code>boost::uint_t&lt;Bits&gt;::fast</code>.
261See the <a href="../integer/integer.htm">integer type selection
262documentation</a> for details.  The <code>TruncPoly</code>,
263<code>InitRem</code>, and <code>FinalXor</code> template parameters also
264are of this type.</p>
265
266<p>This implementation is fast since it uses as many optimizations as
267practical.  All of the CRC parameters are specified at compile-time as
268template parameters.  No individual bits are considered; only whole
269bytes are passed.  A table of interim CRC values versus byte values is
270pre-computed when the first object using a particular bit size,
271truncated 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
276parameters go.  Both class templates use the number of bits in the CRC
277as the first template parameter.  The theoretical computer class
278template has the bit count as its only template parameter, all the other
279CRC parameters are entered through the constructor.  The optimized
280computer class template obtains all its CRC parameters as template
281parameters, and instantiated objects are usually
282default-constructed.</p>
283
284<p>The CRC parameters can be inspected at run-time with the following
285member 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>.
288The fast computer also provides compile-time constants for its CRC
289parameters.</p>
290
291<p>The <code>get_interim_remainder</code> member function returns the
292internal state of the CRC remainder.  It represents the unreflected
293remainder of the last division.  Saving an interim remainder allows the
294freezing of CRC processing, as long as the other CRC parameters and the
295current position of the bit stream are saved.  Restarting a frozen
296stream involves constructing a new computer with the most of the old
297computer's parameters.  The only change is to use the frozen remainder
298as the new computer's initial remainder.  Then the interrupted bit
299stream can be fed as if nothing happened.  The fast CRC computer has a
300special constructor that takes one argument, an interim remainder, for
301this purpose (overriding the initial remainder CRC parameter).</p>
302
303<p>The <code>reset</code> member functions reset the internal state of
304the CRC remainder to the given value.  If no value is given, then the
305internal remainder is set to the initial remainder value when the object
306was created.  The remainder must be unreflected.  When a CRC calculation
307is finished, calling <code>reset</code> lets the object be reused for a
308new session.</p>
309
310<p>After any construction, both CRC computers work the same way.
311Feeding new data to a computer is in a seperate operation(s) from
312extracting the current CRC value from the computer.  The following table
313lists 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 &lt;boost/crc.hpp&gt;      <i>// for boost::crc_basic, boost::crc_optimal</i>
383#include &lt;boost/cstdint.hpp&gt;  <i>// for boost::uint16_t</i>
384
385#include &lt;algorithm&gt;  <i>// for std::for_each</i>
386#include &lt;cassert&gt;    <i>// for assert</i>
387#include &lt;cstddef&gt;    <i>// for std::size_t</i>
388#include &lt;iostream&gt;   <i>// for std::cout</i>
389#include &lt;ostream&gt;    <i>// for std::endl</i>
390
391
392// Main function
393int
394main ()
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&lt;16&gt;  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&lt;16, 0x1021, 0xFFFF, 0, false, false&gt;  crc_ccitt2;
411    crc_ccitt2 = std::for_each( data, data + data_len, crc_ccitt2 );
412    assert( crc_ccitt2() == expected );
413
414    std::cout &lt;&lt; "All tests passed." &lt;&lt; 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 &lt; 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 &gt;
424typename boost::uint_t&lt;Bits&gt;::fast
425boost::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
429given 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
431parameters are passed through template arguments, identical to the
432optimized CRC computer (<a href="#crc_optimal">see above</a>).  In fact,
433such 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 &lt; std::size_t Bits, <em>impl_def</em> TruncPoly &gt;
438typename boost::uint_t&lt;Bits&gt;::fast
439boost::augmented_crc( void const *buffer, std::size_t byte_count,
440 typename boost::uint_t&lt;Bits&gt;::fast initial_remainder );
441
442template &lt; std::size_t Bits, <em>impl_def</em> TruncPoly &gt;
443typename boost::uint_t&lt;Bits&gt;::fast
444boost::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
448that the division steps start immediately on the first message bits.
449The two <code>boost::augmented_crc</code> function templates have a
450different division order.  Instead of combining (<i>via</i> bitwise
451exclusive-or) the current message bit with the highest bit of a separate
452remainder, these templates shift a new message bit into the low bit of a
453remainder register as the highest bit is shifted out.  The new method
454means that the bits in the inital remainder value are processed before
455any of the actual message bits are processed.  To compensate, the real
456CRC can only be extracted after feeding enough zero bits (the same count
457as the register size) after the message bits.</p>
458
459<p>The template parameters of both versions of the function template are
460the CRC's bit size (<code>Bits</code>) and the truncated polynominal
461(<code>TruncPoly</code>).  The version of the function template that
462takes two arguments calls the three-argument version with the
463<var>initial_remainder</var> parameter filled as zero.  Both versions
464work 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
468follow the message's bytes.  First, set the bytes of where the CRC will
469go to zero.  Then use <code>augmented_crc</code> over the augmented
470message, <i>i.e.</i> the message bytes and the appended CRC bytes.  Then
471assign the result to the CRC.  To later check a received message, either
472use <code>augmented_crc</code> (with the same parameters as
473transmission, of course) on the received <em>unaugmented</em> message
474and check if the result equals the CRC, or use
475<code>augmented_crc</code> on the received <em>augmented</em> message
476and check if the result equals zero.  Note that the CRC has to be stored
477with 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
482the next data block.  Remember that the actual CRC can only be
483determined after feeding the augmented bytes.  Since this method uses
484modulo-2 polynominal division at its most raw, neither final XOR values
485nor reflection can be used.</p>
486
487<p>Note that for the same CRC system, the initial remainder for
488augmented message method will be different than for the unaugmented
489message method.  The main exception is zero; if the augmented-CRC
490algorithm uses a zero initial remainder, the equivalent unaugmented-CRC
491algorithm will also use a zero initial remainder.  Given an initial
492remainder for a augmented-CRC algorithm, the result from processing just
493zero-valued CRC bytes without any message bytes is the equivalent inital
494remainder for the unaugmented-CRC algorithm.  An example follows:</p>
495
496<blockquote><pre>#include &lt;boost/crc.hpp&gt;      <i>// for boost::crc_basic, boost::augmented_crc</i>
497#include &lt;boost/cstdint.hpp&gt;  <i>// for boost::uint16_t</i>
498
499#include &lt;cassert&gt;    <i>// for assert</i>
500#include &lt;iostream&gt;   <i>// for std::cout</i>
501#include &lt;ostream&gt;    <i>// for std::endl</i>
502
503
504// Main function
505int
506main ()
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&lt;16, 0x8005&gt;( data, sizeof(data), init_rem );
515
516    uint16_t const  zero = 0;
517    uint16_t const  new_init_rem = augmented_crc&lt;16, 0x8005&gt;( &amp;zero, sizeof(zero) );
518
519    boost::crc_basic&lt;16&gt;  crc2( 0x8005, new_init_rem );
520    crc2.process_block( data, &amp;data[5] );  // don't include CRC
521    assert( crc2.checksum() == crc1 );
522
523    std::cout &lt;&lt; "All tests passed." &lt;&lt; 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
531algorithms.  For example, computations from <code>boost::crc_32_type</code>
532can be used for implementing the PKZip standard.  Note that, in general, this
533library is concerned with CRC implementation, and not with determining
534&quot;good&quot; 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&eacute; Consultatif International
549                    T&eacute;l&eacute;graphique et T&eacute;l&eacute;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 &quot;Slow and Steady
582                Never Lost the Race&quot; in the January 2000 issue of <cite><a
583                href="http://www.embedded.com/">Embedded Systems
584                Programming</a></cite>, pages 37&ndash;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,
602interface, 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
630are subject to the Boost Software License, Version 1.0.  (See accompanying
631file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at
632&lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</p>
633
634</body>
635</html>
Note: See TracBrowser for help on using the repository browser.