Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

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 Rocksoft™ Model CRC Algorithm parameter as a template parameter, the WIDTH, which determines the built-in unsigned integer type used for division registers. The other Rocksoft™ Model CRC Algorithm 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 Rocksoft™ Model CRC Algorithm attributes can be discovered as:

Table 10.1. 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.

Here's an example of reuse:

std::pair<unsigned, unsigned> crc_16_and_xmodem( void const *b, std::size_t l )
{
    std::pair<unsigned, unsigned>  result;
    1boost::crc_basic<16>           crc1( 0x8005u, 0u, 0u, true, true );

    crc1.process_bytes( b, l );
    result.first = crc1.checksum();
    2crc1 = boost::crc_basic<16>( 0x8408u, crc1.get_initial_remainder(),
     crc1.get_final_xor_value(), crc1.get_reflect_input(),
     crc1.get_reflect_remainder() );
    crc1.process_bytes( b, l );
    result.second = crc1.checksum();

    return result;
}

For now, most Rocksoft™ Model CRC Algorithm parameters can only be changed through assignment to the entire object.

1

The parameters are based on boost::crc_16_type.

2

Change the parameters to match boost::crc_xmodem_type.

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

Persistent objects mean that the data doesn't have to be in one block:

unsigned  combined_crc_16( unsigned block_count, ... )
{
    1using namespace std;

    2boost::crc_basic<16>  crc1( 0x8005u, 0u, 0u, true, true );
    va_list               ap;

    va_start( ap, block_count );
    while ( block_count-- )
    {
        void const * const  bs = va_arg( ap, void const * );
        size_t const        bl = va_arg( ap, size_t );

        3crc1.process_bytes( bs, bl );
    }
    va_end( ap );

    return crc1.checksum();
}

No CRC operation throws, so there is no need for extra protection between the varargs macro calls.

1

C-style variable-argument routines are or may be macros.

2

The parameters are based on boost::crc_16_type.

3

The va_arg calls were within the process_bytes call, but I remembered that calling order is not guaranteed among function arguments, so I need explicit object declarations to enforce the extraction order.

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 Rocksoft™ Model CRC Algorithm 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.


PrevUpHomeNext