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


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

The augmented_crc function can compute CRCs from distributed data, too:

unsigned  combined_acrc_16( int block_count, ... )
    1using namespace std;

    va_list   ap;
    unsigned  result = 0u;

    va_start( ap, block_count );
    if ( block_count <= 0 )
        goto finish;

    void const *  bs = va_arg( ap, void const * );
    size_t        bl = va_arg( ap, size_t );

    2result = boost::augmented_crc<16, 0x1021u>( bs, bl );
    while ( --block_count )
        bs = va_arg( ap, void const * );
        bl = va_arg( ap, size_t );
        result = boost::augmented_crc<16, 0x1021u>( bs, bl, result );

    va_end( ap );
    return result;

No CRC operation throws, so there is no need for extra protection between the varargs macro calls. Feeding the result from the previous run as the initial remainder for the next run works easily because there's no output reflection or XOR mask.


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


The parameters are based on boost::crc_xmodem_t.

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