#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 ); }
boost::augmented_crc
函数计算数据块的增强型 CRC。与 boost::crc
类似,前两个模板参数是 WIDTH 和 POLY。但是,INIT 已移至函数参数,位于数据块的起始地址和字节长度之后,如果未提供,则默认为零。
此函数以最原始的方式使用模 2 除法,因此放弃了 REFIN、REFOUT 和 XOROUT 属性,并将它们设置为 0
或 false
。与 boost::crc
的另一个不同之处在于,当与此函数一起使用时,非零 INIT 必须进行调整。(目前未提供转换函数。)
augmented_crc
函数也可以从分布式数据计算 CRC
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; }
没有 CRC 操作会抛出异常,因此无需在可变参数宏调用之间进行额外的保护。将前一次运行的结果作为下一次运行的初始余数非常容易,因为没有输出反射或 XOR 掩码。
由于 augmented_crc
不知道您的数据何时结束,因此您必须提供增广,可以是 WIDTH 个零位或预期的校验和。增广可以在最后一个数据块的末尾,也可以通过额外的调用提供。请记住,如果将预期的校验和用作增广,则其位必须以大端序排列。由于 augmented_crc
按字节读取,而增广假设按位读取,因此只有当 WIDTH 是每字节位数 (CHAR_BIT
) 的倍数时,增广才有效。