循环冗余校验(CRC)是一种根据网络数据封包或电脑档案等数据产生简短固定位数的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。它是由W. Wesley Peterson在他1961年发表的论文中披露。[来自维基百科]
CRC校验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码) r位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端, 则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。
假设要生成一个16位的CRC码,它产生的规则是先将要发送的二进制序列数左移16位(既乘以216)后,再除以一个多项式,最后所得到的余数既是CRC码。任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’ 和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为 x5+x3+x2+x+1对应的代码101111。
Boost里的CRC库
Boost中的CRC库定义于头文件<boost/crc.hpp>中,主要提供了两个CRC类:class crc_basic和class crc_optimal。crc_basic 是按位运算的,速度较慢。crc_optimal按位数取相应的字节数作为单位运算,速度很快。
crc_basic和crc_optimal的用法相差不大,主要区别是CRC参数设定的位置不同,下面是它们的类声明和构造函数
template < std::size_t Bits > class crc_basic; explicit crc_basic( value_type truncated_polynominal, value_type initial_remainder = 0, value_type final_xor_value = 0, bool reflect_input = false, bool reflect_remainder = false ); template < std::size_t Bits, impl_def TruncPoly = 0u, impl_def InitRem = 0u, impl_def FinalXor = 0u, bool ReflectIn = false, bool ReflectRem = false > class crc_optimal; explicit crc_optimal( value_type init_rem = InitRem );
对比crc_basic构造函数参数名和crc_optimal模板参数名,可以看出其实它们是一样的。只是crc_basic在构造函数里设置CRC参数,而crc_optimal是在模板参数里。
下面先说说这几个参数的意义:
Bits | CRC校验位数 |
truncated_polynominal/TruncPoly | 多项式,由于除数总是比余数大一位,而作为除数的多项式最高位总是为1。在描述CRC多项式时,最高位被忽略,这样可以让多项式(除数)和CRC校验和(余数)使用同一数据类型来表示。 |
initial_remainder/InitRem | 初始值 |