Augmented-CRC Function

| Home | Libraries | People | FAQ | More

## 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, ... )
    {
        using 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 );

        result = 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 );
        }

    finish:
        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`).