1 // Boost CRC test program file ---------------------------------------------//
3 // Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and
4 // distribution are subject to the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or a copy at
6 // <http://www.boost.org/LICENSE_1_0.txt>.)
8 // See <http://www.boost.org/libs/crc/> for the library's home page.
11 // 28 Aug 2004 Added CRC tests for polynominals shorter than 8 bits
12 // (Daryle Walker, by patch from Bert Klaps)
13 // 23 Aug 2003 Adjust to updated Test framework (Daryle Walker)
14 // 14 May 2001 Initial version (Daryle Walker)
17 #include <boost/config.hpp> // for BOOST_MSVC, etc.
18 #include <boost/crc.hpp> // for boost::crc_basic, etc.
19 #include <boost/cstdint.hpp> // for boost::uint16_t, etc.
20 #include <boost/cstdlib.hpp> // for boost::exit_success
21 #include <boost/integer.hpp> // for boost::uint_t
22 #include <boost/random/linear_congruential.hpp> // for boost::minstd_rand
23 #include <boost/test/minimal.hpp> // for main, etc.
24 #include <boost/timer.hpp> // for boost::timer
26 #include <algorithm> // for std::for_each, std::generate_n, std::count
27 #include <climits> // for CHAR_BIT
28 #include <cstddef> // for std::size_t
29 #include <iostream> // for std::cout (std::ostream and std::endl indirectly)
33 #error The expected results assume an eight-bit byte.
36 #if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) || (defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)))
37 #define CRC_PARM_TYPE typename boost::uint_t<Bits>::fast
39 #define CRC_PARM_TYPE unsigned long
42 #if !defined(BOOST_MSVC) && !defined(__GNUC__)
43 #define PRIVATE_DECLARE_BOOST( TypeName ) using boost:: TypeName
45 #define PRIVATE_DECLARE_BOOST( TypeName ) typedef boost:: TypeName TypeName
50 template < std::size_t Bits
, CRC_PARM_TYPE TrPo
, CRC_PARM_TYPE InRe
,
51 CRC_PARM_TYPE FiXo
, bool ReIn
, bool ReRe
>
55 // All the following were separate function templates, but they have
56 // been moved to class-static member functions of a class template
57 // because MS VC++ 6 can't handle function templates that can't
58 // deduce all their template arguments from their function arguments.
60 typedef typename
boost::uint_t
<Bits
>::fast value_type
;
62 static void master_test( char const *test_name
, value_type expected
);
65 typedef boost::crc_optimal
<Bits
, TrPo
, InRe
, FiXo
, ReIn
, ReRe
>
67 typedef boost::crc_basic
<Bits
> basic_crc_type
;
69 static void compute_test( value_type expected
);
70 static void interrupt_test( value_type expected
);
71 static void error_test();
76 unsigned char const std_data
[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
78 std::size_t const std_data_len
= sizeof( std_data
) / sizeof( std_data
[0] );
80 boost::uint16_t const std_crc_ccitt_result
= 0x29B1;
81 boost::uint16_t const std_crc_16_result
= 0xBB3D;
82 boost::uint32_t const std_crc_32_result
= 0xCBF43926;
84 // Function prototypes
86 boost::uint32_t basic_crc32( void const *buffer
, std::size_t byte_count
);
87 boost::uint32_t optimal_crc32( void const *buffer
, std::size_t byte_count
);
88 boost::uint32_t quick_crc32( void const *buffer
, std::size_t byte_count
);
89 boost::uint32_t quick_reflect( boost::uint32_t value
, std::size_t bits
);
90 double time_trial( char const *name
,
91 boost::uint32_t (*crc_func
)(void const *, std::size_t),
92 boost::uint32_t expected
, void const *data
, std::size_t length
);
94 void augmented_tests();
95 boost::uint32_t native_to_big( boost::uint32_t x
);
96 boost::uint32_t big_to_native( boost::uint32_t x
);
98 void small_crc_test1();
99 void small_crc_test2();
102 // Macro to compact code
103 #define PRIVATE_TESTER_NAME crc_tester<Bits, TrPo, InRe, FiXo, ReIn, ReRe>
105 // Run a test on slow and fast CRC computers and function
106 template < std::size_t Bits
, CRC_PARM_TYPE TrPo
, CRC_PARM_TYPE InRe
,
107 CRC_PARM_TYPE FiXo
, bool ReIn
, bool ReRe
>
109 PRIVATE_TESTER_NAME::compute_test
111 typename
PRIVATE_TESTER_NAME::value_type expected
114 std::cout
<< "\tDoing computation tests." << std::endl
;
116 optimal_crc_type fast_crc
;
117 basic_crc_type
slow_crc( TrPo
, InRe
, FiXo
, ReIn
, ReRe
);
118 value_type
const func_result
= boost::crc
<Bits
, TrPo
, InRe
, FiXo
, ReIn
,
119 ReRe
>( std_data
, std_data_len
);
121 fast_crc
.process_bytes( std_data
, std_data_len
);
122 slow_crc
.process_bytes( std_data
, std_data_len
);
123 BOOST_CHECK( fast_crc
.checksum() == expected
);
124 BOOST_CHECK( slow_crc
.checksum() == expected
);
125 BOOST_CHECK( func_result
== expected
);
128 // Run a test in two runs, and check all the inspectors
129 template < std::size_t Bits
, CRC_PARM_TYPE TrPo
, CRC_PARM_TYPE InRe
,
130 CRC_PARM_TYPE FiXo
, bool ReIn
, bool ReRe
>
132 PRIVATE_TESTER_NAME::interrupt_test
134 typename
PRIVATE_TESTER_NAME::value_type expected
137 std::cout
<< "\tDoing interrupt tests." << std::endl
;
139 // Process the first half of the data (also test accessors)
140 optimal_crc_type fast_crc1
;
141 basic_crc_type
slow_crc1( fast_crc1
.get_truncated_polynominal(),
142 fast_crc1
.get_initial_remainder(), fast_crc1
.get_final_xor_value(),
143 fast_crc1
.get_reflect_input(), fast_crc1
.get_reflect_remainder() );
145 BOOST_CHECK( fast_crc1
.get_interim_remainder() ==
146 slow_crc1
.get_initial_remainder() );
148 std::size_t const mid_way
= std_data_len
/ 2;
149 unsigned char const * const std_data_end
= std_data
+ std_data_len
;
151 fast_crc1
.process_bytes( std_data
, mid_way
);
152 slow_crc1
.process_bytes( std_data
, mid_way
);
153 BOOST_CHECK( fast_crc1
.checksum() == slow_crc1
.checksum() );
155 // Process the second half of the data (also test accessors)
156 boost::crc_optimal
<optimal_crc_type::bit_count
,
157 optimal_crc_type::truncated_polynominal
, optimal_crc_type::initial_remainder
,
158 optimal_crc_type::final_xor_value
, optimal_crc_type::reflect_input
,
159 optimal_crc_type::reflect_remainder
>
160 fast_crc2( fast_crc1
.get_interim_remainder() );
161 boost::crc_basic
<basic_crc_type::bit_count
> slow_crc2(
162 slow_crc1
.get_truncated_polynominal(), slow_crc1
.get_interim_remainder(),
163 slow_crc1
.get_final_xor_value(), slow_crc1
.get_reflect_input(),
164 slow_crc1
.get_reflect_remainder() );
166 fast_crc2
.process_block( std_data
+ mid_way
, std_data_end
);
167 slow_crc2
.process_block( std_data
+ mid_way
, std_data_end
);
168 BOOST_CHECK( fast_crc2
.checksum() == slow_crc2
.checksum() );
169 BOOST_CHECK( fast_crc2
.checksum() == expected
);
170 BOOST_CHECK( slow_crc2
.checksum() == expected
);
173 // Run a test to see if a single-bit error is detected
174 template < std::size_t Bits
, CRC_PARM_TYPE TrPo
, CRC_PARM_TYPE InRe
,
175 CRC_PARM_TYPE FiXo
, bool ReIn
, bool ReRe
>
177 PRIVATE_TESTER_NAME::error_test
181 PRIVATE_DECLARE_BOOST( uint32_t );
183 // A single-bit error is ensured to be detected if the polynominal
184 // has at least two bits set. The highest bit is what is removed
185 // to give the truncated polynominal, and it is always set. This
186 // means that the truncated polynominal needs at least one of its
187 // bits set, which implies that it cannot be zero.
188 if ( !(TrPo
& boost::detail::mask_uint_t
<Bits
>::sig_bits_fast
) )
190 BOOST_FAIL( "truncated CRC polymonial is zero" );
193 std::cout
<< "\tDoing error tests." << std::endl
;
195 // Create a random block of data
196 uint32_t ran_data
[ 256 ];
197 std::size_t const ran_length
= sizeof(ran_data
) / sizeof(ran_data
[0]);
199 std::generate_n( ran_data
, ran_length
, boost::minstd_rand() );
201 // Create computers and compute the checksum of the data
202 optimal_crc_type fast_tester
;
203 basic_crc_type
slow_tester( TrPo
, InRe
, FiXo
, ReIn
, ReRe
);
205 fast_tester
.process_bytes( ran_data
, sizeof(ran_data
) );
206 slow_tester
.process_bytes( ran_data
, sizeof(ran_data
) );
208 uint32_t const fast_checksum
= fast_tester
.checksum();
209 uint32_t const slow_checksum
= slow_tester
.checksum();
211 BOOST_CHECK( fast_checksum
== slow_checksum
);
213 // Do the checksum again (and test resetting ability)
215 slow_tester
.reset( InRe
);
216 fast_tester
.process_bytes( ran_data
, sizeof(ran_data
) );
217 slow_tester
.process_bytes( ran_data
, sizeof(ran_data
) );
218 BOOST_CHECK( fast_tester
.checksum() == slow_tester
.checksum() );
219 BOOST_CHECK( fast_tester
.checksum() == fast_checksum
);
220 BOOST_CHECK( slow_tester
.checksum() == slow_checksum
);
222 // Produce a single-bit error
223 ran_data
[ ran_data
[0] % ran_length
] ^= ( 1 << (ran_data
[1] % 32) );
225 // Compute the checksum of the errorenous data
226 // (and continue testing resetting ability)
227 fast_tester
.reset( InRe
);
229 fast_tester
.process_bytes( ran_data
, sizeof(ran_data
) );
230 slow_tester
.process_bytes( ran_data
, sizeof(ran_data
) );
231 BOOST_CHECK( fast_tester
.checksum() == slow_tester
.checksum() );
232 BOOST_CHECK( fast_tester
.checksum() != fast_checksum
);
233 BOOST_CHECK( slow_tester
.checksum() != slow_checksum
);
236 // Run the other CRC object tests
237 template < std::size_t Bits
, CRC_PARM_TYPE TrPo
, CRC_PARM_TYPE InRe
,
238 CRC_PARM_TYPE FiXo
, bool ReIn
, bool ReRe
>
240 PRIVATE_TESTER_NAME::master_test
242 char const * test_name
,
243 typename
PRIVATE_TESTER_NAME::value_type expected
246 std::cout
<< "Doing test suite for " << test_name
<< '.' << std::endl
;
247 compute_test( expected
);
248 interrupt_test( expected
);
252 // Undo limited macros
253 #undef PRIVATE_TESTER_NAME
256 // A CRC-32 computer based on crc_basic, for timing
261 std::size_t byte_count
264 static boost::crc_basic
<32> computer( 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF,
268 computer
.process_bytes( buffer
, byte_count
);
269 return computer
.checksum();
272 // A CRC-32 computer based on crc_optimal, for timing
278 std::size_t byte_count
281 static boost::crc_32_type computer
;
284 computer
.process_bytes( buffer
, byte_count
);
285 return computer
.checksum();
288 // Reflect the lower "bits" bits of a "value"
292 boost::uint32_t value
,
296 boost::uint32_t reflection
= 0;
297 for ( std::size_t i
= 0 ; i
< bits
; ++i
)
299 if ( value
& (1u << i
) )
301 reflection
|= 1 << ( bits
- 1 - i
);
308 // A customized CRC-32 computer, for timing
313 std::size_t byte_count
316 PRIVATE_DECLARE_BOOST( uint32_t );
317 typedef unsigned char byte_type
;
319 // Compute the CRC table (first run only)
320 static bool did_init
= false;
321 static uint32_t crc_table
[ 1ul << CHAR_BIT
];
324 uint32_t const value_high_bit
= static_cast<uint32_t>(1) << 31u;
326 byte_type dividend
= 0;
329 uint32_t remainder
= 0;
330 for ( byte_type mask
= 1u << (CHAR_BIT
- 1u) ; mask
; mask
>>= 1 )
332 if ( dividend
& mask
)
334 remainder
^= value_high_bit
;
337 if ( remainder
& value_high_bit
)
340 remainder
^= 0x04C11DB7u
;
348 crc_table
[ quick_reflect(dividend
, CHAR_BIT
) ]
349 = quick_reflect( remainder
, 32 );
351 while ( ++dividend
);
356 // Compute the CRC of the data
357 uint32_t rem
= 0xFFFFFFFF;
359 byte_type
const * const b_begin
= static_cast<byte_type
const *>( buffer
);
360 byte_type
const * const b_end
= b_begin
+ byte_count
;
361 for ( byte_type
const *p
= b_begin
; p
< b_end
; ++p
)
363 byte_type
const byte_index
= *p
^ rem
;
365 rem
^= crc_table
[ byte_index
];
371 // Run an individual timing trial
376 boost::uint32_t (*crc_func
)(void const *, std::size_t),
377 boost::uint32_t expected
,
382 PRIVATE_DECLARE_BOOST( uint32_t );
386 static uint32_t const max_count
= 1L << 16; // ~square-root of max
387 static double const max_time
= 3.14159; // easy as pi(e)
390 cout
<< '\t' << name
<< " CRC-32: ";
393 uint32_t trial_count
= 0, wrong_count
= 0;
394 double elapsed_time
= 0.0;
399 uint32_t const scratch
= (*crc_func
)( data
, length
);
401 if ( scratch
!= expected
)
405 elapsed_time
= t
.elapsed();
407 } while ( (trial_count
< max_count
) && (elapsed_time
< max_time
) );
411 BOOST_ERROR( "at least one time trial didn't match expected" );
415 double const rate
= trial_count
/ elapsed_time
;
417 cout
<< trial_count
<< " runs, " << elapsed_time
<< " s, " << rate
418 << " run/s" << std::endl
;
422 // Time runs of Boost CRCs vs. a customized CRC function
428 PRIVATE_DECLARE_BOOST( uint32_t );
432 cout
<< "Doing timing tests." << endl
;
434 // Create a random block of data
435 boost::int32_t ran_data
[ 256 ];
436 std::size_t const ran_length
= sizeof(ran_data
) / sizeof(ran_data
[0]);
438 std::generate_n( ran_data
, ran_length
, boost::minstd_rand() );
440 // Use the first runs as a check. This gives a chance for first-
441 // time static initialization to not interfere in the timings.
442 uint32_t const basic_result
= basic_crc32( ran_data
, sizeof(ran_data
) );
443 uint32_t const optimal_result
= optimal_crc32( ran_data
, sizeof(ran_data
) );
444 uint32_t const quick_result
= quick_crc32( ran_data
, sizeof(ran_data
) );
446 BOOST_CHECK( basic_result
== optimal_result
);
447 BOOST_CHECK( optimal_result
== quick_result
);
448 BOOST_CHECK( quick_result
== basic_result
);
451 double const basic_rate
= time_trial( "Boost-Basic", basic_crc32
,
452 basic_result
, ran_data
, sizeof(ran_data
) );
453 double const optimal_rate
= time_trial( "Boost-Optimal", optimal_crc32
,
454 optimal_result
, ran_data
, sizeof(ran_data
) );
455 double const quick_rate
= time_trial( "Reference", quick_crc32
,
456 quick_result
, ran_data
, sizeof(ran_data
) );
459 cout
<< "\tThe optimal Boost version is " << (quick_rate
- optimal_rate
)
460 / quick_rate
* 100.0 << "% slower than the reference version.\n";
461 cout
<< "\tThe basic Boost version is " << (quick_rate
- basic_rate
)
462 / quick_rate
* 100.0 << "% slower than the reference version.\n";
463 cout
<< "\tThe basic Boost version is " << (optimal_rate
- basic_rate
)
464 / optimal_rate
* 100.0 << "% slower than the optimal Boost version."
469 // Reformat an integer to the big-endian storage format
476 boost::uint32_t temp
;
477 unsigned char * tp
= reinterpret_cast<unsigned char *>( &temp
);
479 for ( std::size_t i
= sizeof(x
) ; i
> 0 ; --i
)
481 tp
[ i
- 1 ] = static_cast<unsigned char>( x
);
488 // Restore an integer from the big-endian storage format
495 boost::uint32_t temp
= 0;
496 unsigned char * xp
= reinterpret_cast<unsigned char *>( &x
);
498 for ( std::size_t i
= 0 ; i
< sizeof(x
) ; ++i
)
507 // Run tests on using CRCs on augmented messages
513 #define PRIVATE_ACRC_FUNC boost::augmented_crc<32, 0x04C11DB7>
516 PRIVATE_DECLARE_BOOST( uint32_t );
518 std::cout
<< "Doing CRC-augmented message tests." << std::endl
;
520 // Create a random block of data, with space for a CRC.
521 uint32_t ran_data
[ 257 ];
522 size_t const ran_length
= sizeof(ran_data
) / sizeof(ran_data
[0]);
523 size_t const data_length
= ran_length
- 1;
525 std::generate_n( ran_data
, data_length
, boost::minstd_rand() );
527 // When creating a CRC for an augmented message, use
528 // zeros in the appended CRC spot for the first run.
529 uint32_t & ran_crc
= ran_data
[ data_length
];
533 // Compute the CRC with augmented-CRC computing function
534 typedef boost::uint_t
<32>::fast return_type
;
536 ran_crc
= PRIVATE_ACRC_FUNC( ran_data
, sizeof(ran_data
) );
538 // With the appended CRC set, running the checksum again should get zero.
539 // NOTE: CRC algorithm assumes numbers are in big-endian format
540 ran_crc
= native_to_big( ran_crc
);
542 uint32_t ran_crc_check
= PRIVATE_ACRC_FUNC( ran_data
, sizeof(ran_data
) );
544 BOOST_CHECK( 0 == ran_crc_check
);
546 // Compare that result with other CRC computing functions
547 // and classes, which don't accept augmented messages.
548 typedef boost::crc_optimal
<32, 0x04C11DB7> fast_crc_type
;
549 typedef boost::crc_basic
<32> slow_crc_type
;
551 fast_crc_type fast_tester
;
552 slow_crc_type
slow_tester( 0x04C11DB7 );
553 size_t const data_size
= data_length
* sizeof(ran_data
[0]);
554 uint32_t const func_tester
= boost::crc
<32, 0x04C11DB7, 0, 0, false,
555 false>( ran_data
, data_size
);
557 fast_tester
.process_bytes( ran_data
, data_size
);
558 slow_tester
.process_bytes( ran_data
, data_size
);
559 BOOST_CHECK( fast_tester
.checksum() == slow_tester
.checksum() );
560 ran_crc
= big_to_native( ran_crc
);
561 BOOST_CHECK( fast_tester
.checksum() == ran_crc
);
562 BOOST_CHECK( func_tester
== ran_crc
);
564 // Do a single-bit error test
565 ran_crc
= native_to_big( ran_crc
);
566 ran_data
[ ran_data
[0] % ran_length
] ^= ( 1 << (ran_data
[1] % 32) );
567 ran_crc_check
= PRIVATE_ACRC_FUNC( ran_data
, sizeof(ran_data
) );
568 BOOST_CHECK( 0 != ran_crc_check
);
570 // Run a version of these tests with a nonzero initial remainder.
571 uint32_t const init_rem
= ran_data
[ ran_data
[2] % ran_length
];
574 ran_crc
= PRIVATE_ACRC_FUNC( ran_data
, sizeof(ran_data
), init_rem
);
576 // Have some fun by processing data in two steps.
577 size_t const mid_index
= ran_length
/ 2;
579 ran_crc
= native_to_big( ran_crc
);
580 ran_crc_check
= PRIVATE_ACRC_FUNC( ran_data
, mid_index
581 * sizeof(ran_data
[0]), init_rem
);
582 ran_crc_check
= PRIVATE_ACRC_FUNC( &ran_data
[mid_index
], sizeof(ran_data
)
583 - mid_index
* sizeof(ran_data
[0]), ran_crc_check
);
584 BOOST_CHECK( 0 == ran_crc_check
);
586 // This substep translates an augmented-CRC initial
587 // remainder to an unaugmented-CRC initial remainder.
588 uint32_t const zero
= 0;
589 uint32_t const new_init_rem
= PRIVATE_ACRC_FUNC( &zero
, sizeof(zero
),
591 slow_crc_type
slow_tester2( 0x04C11DB7, new_init_rem
);
593 slow_tester2
.process_bytes( ran_data
, data_size
);
594 ran_crc
= big_to_native( ran_crc
);
595 BOOST_CHECK( slow_tester2
.checksum() == ran_crc
);
597 // Redo single-bit error test
598 ran_data
[ ran_data
[3] % ran_length
] ^= ( 1 << (ran_data
[4] % 32) );
599 ran_crc_check
= PRIVATE_ACRC_FUNC( ran_data
, sizeof(ran_data
), init_rem
);
600 BOOST_CHECK( 0 != ran_crc_check
);
602 #undef PRIVATE_ACRC_FUNC
606 // Run tests on CRCs below a byte in size (here, 3 bits)
612 std::cout
<< "Doing short-CRC (3-bit augmented) message tests."
615 // The CRC standard is a SDH/SONET Low Order LCAS control word with CRC-3
616 // taken from ITU-T G.707 (12/03) XIII.2.
618 // Four samples, each four bytes; should all have a CRC of zero
619 unsigned char const samples
[4][4]
621 { 0x3A, 0xC4, 0x08, 0x06 },
622 { 0x42, 0xC5, 0x0A, 0x41 },
623 { 0x4A, 0xC5, 0x08, 0x22 },
624 { 0x52, 0xC4, 0x08, 0x05 }
628 boost::crc_basic
<3> tester1( 0x03 );
630 tester1
.process_bytes( samples
[0], 4 );
631 BOOST_CHECK( tester1
.checksum() == 0 );
634 tester1
.process_bytes( samples
[1], 4 );
635 BOOST_CHECK( tester1
.checksum() == 0 );
638 tester1
.process_bytes( samples
[2], 4 );
639 BOOST_CHECK( tester1
.checksum() == 0 );
642 tester1
.process_bytes( samples
[3], 4 );
643 BOOST_CHECK( tester1
.checksum() == 0 );
646 #define PRIVATE_CRC_FUNC boost::crc<3, 0x03, 0, 0, false, false>
647 #define PRIVATE_ACRC_FUNC boost::augmented_crc<3, 0x03>
649 BOOST_CHECK( 0 == PRIVATE_CRC_FUNC(samples
[0], 4) );
650 BOOST_CHECK( 0 == PRIVATE_CRC_FUNC(samples
[1], 4) );
651 BOOST_CHECK( 0 == PRIVATE_CRC_FUNC(samples
[2], 4) );
652 BOOST_CHECK( 0 == PRIVATE_CRC_FUNC(samples
[3], 4) );
654 // maybe the fix to CRC functions needs to be applied to augmented CRCs?
656 #undef PRIVATE_ACRC_FUNC
657 #undef PRIVATE_CRC_FUNC
660 // Run tests on CRCs below a byte in size (here, 7 bits)
666 std::cout
<< "Doing short-CRC (7-bit augmented) message tests."
669 // The CRC standard is a SDH/SONET J0/J1/J2/N1/N2/TR TTI (trace message)
670 // with CRC-7, o.a. ITU-T G.707 Annex B, G.832 Annex A.
672 // Two samples, each sixteen bytes
673 // Sample 1 is '\x80' + ASCII("123456789ABCDEF")
674 // Sample 2 is '\x80' + ASCII("TTI UNAVAILABLE")
675 unsigned char const samples
[2][16]
677 { 0x80, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41,
678 0x42, 0x43, 0x44, 0x45, 0x46 },
679 { 0x80, 0x54, 0x54, 0x49, 0x20, 0x55, 0x4E, 0x41, 0x56, 0x41, 0x49,
680 0x4C, 0x41, 0x42, 0x4C, 0x45 }
682 unsigned const results
[2] = { 0x62, 0x23 };
685 boost::crc_basic
<7> tester1( 0x09 );
687 tester1
.process_bytes( samples
[0], 16 );
688 BOOST_CHECK( tester1
.checksum() == results
[0] );
691 tester1
.process_bytes( samples
[1], 16 );
692 BOOST_CHECK( tester1
.checksum() == results
[1] );
695 #define PRIVATE_CRC_FUNC boost::crc<7, 0x09, 0, 0, false, false>
696 #define PRIVATE_ACRC_FUNC boost::augmented_crc<7, 0x09>
698 BOOST_CHECK( results
[0] == PRIVATE_CRC_FUNC(samples
[0], 16) );
699 BOOST_CHECK( results
[1] == PRIVATE_CRC_FUNC(samples
[1], 16) );
701 // maybe the fix to CRC functions needs to be applied to augmented CRCs?
703 #undef PRIVATE_ACRC_FUNC
704 #undef PRIVATE_CRC_FUNC
709 // Explicit template instantiations
710 // (needed to fix a link error in Metrowerks CodeWarrior Pro 5.3)
711 template class crc_tester
<16, 0x1021, 0xFFFF, 0, false, false>;
712 template class crc_tester
<16, 0x8005, 0, 0, true, true>;
713 template class crc_tester
<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>;
716 // Main testing function
720 int , // "argc" is unused
721 char * [] // "argv" is unused
727 // Run simulations on some CRC types
728 typedef crc_tester
<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_tester
;
729 typedef crc_tester
<16, 0x8005, 0, 0, true, true> crc_16_tester
;
730 typedef crc_tester
<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
733 crc_ccitt_tester::master_test( "CRC-CCITT", std_crc_ccitt_result
);
734 crc_16_tester::master_test( "CRC-16", std_crc_16_result
);
735 crc_32_tester::master_test( "CRC-32", std_crc_32_result
);
737 // Run a timing comparison test
740 // Test using augmented messages
743 // Test with CRC types smaller than a byte
747 // Try a CRC based on the (x + 1) polynominal, which is a factor in
748 // many real-life polynominals and doesn't fit evenly in a byte.
749 cout
<< "Doing one-bit polynominal CRC test." << endl
;
750 boost::crc_basic
<1> crc_1( 1 );
751 crc_1
.process_bytes( std_data
, std_data_len
);
752 BOOST_CHECK( crc_1
.checksum() == 1 );
754 // Test the function object interface
755 cout
<< "Doing functional object interface test." << endl
;
756 boost::crc_optimal
<16, 0x8005, 0, 0, true, true> crc_16
;
757 crc_16
= std::for_each( std_data
, std_data
+ std_data_len
, crc_16
);
758 BOOST_CHECK( crc_16() == std_crc_16_result
);
760 return boost::exit_success
;