循环冗余校验(CRC)是一种根据网络数据封包或电脑档案等数据产生简短固定位数的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者储存之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。由于本函数易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。它是由W. Wesley Peterson在他1961年发表的论文中披露[1]。
目录
|
CRC“校验和”(checksum)是两个位元数据流采用二进制除法(没有进位,使用XOR异或来代替减法)相除所得到的余数。其中被除数是需要计算校验和的信息数据流的二进制表示;除数是一个长度为n + 1的预定义(短)的二进制数,通常用多项式的系数来表示。在做除法之前,要在信息数据之后先加上n个0.
CRCa 是基于有限域 GF(2) (即除以2的同余)的多项式环。简单的来说,就是所有系数都为0或1(又叫做二进制)的多项式系数的集合,并且集合对于所有的代数操作都是封闭的。例如:
2会变成0,因为对系数的加法运算都会再取2的模数. 乘法也是类似的:
我们同样可以对多项式作除法并且得到商和余数。例如, 如果我们用x3 + x2 + x除以x + 1。我们会得到:
也就是说,
这里除法得到了商x2 + 1和余数-1,因为是奇数所以最后一位是1。
字符串中的每一位其实就对应了这样类型的多项式的系数。为了得到CRC, 我们首先将其乘以xn,这里n是一个固定多项式的阶数, 然后再将其除以这个固定的多项式,余数的系数就是CRC。
在上面的等式中,x2 + x + 1表示了本来的信息位是111
, x + 1是所谓的钥匙, 而余数1(也就是x0)就是CRC. key的最高次为1, 所以我们将原来的信息乘上x1来得到x3 + x2 + x,也可视为原来的信息位补1个零成为1110
。
一般来说,其形式为:
这里 M(x) 是原始的信息多项式。K(x)是n阶的“钥匙”多项式。表示了将原始信息后面加上n个0。R(x)是余数多项式,既是CRC“校验和”。在通讯中,发送者在原始的信息数据M后加上n位的R(替换本来附加的0)再发送。接收者收到M和R后,检查是否能被K(x)整除。如果是,那么接收者认为该信息是正确的。值得注意的是就是发送者所想要发送的数据。这个串又叫做codeword.
CRCs 经常被叫做“校验和”, 但是这样的说法严格来说并不是准确的,因为技术上来说,校验“和”是通过加法来计算的,而不是CRC这里的除法。
“错误纠正编码”常常和CRCs紧密相关,其语序纠正在传输过程中所产生的错误。这些编码方式常常和数学原理紧密相关。
CRC 有几种不同的变体
shiftRegister
可以逆向使用,这样就需要检测最低位的值,每次向右移动一位。这就要求 polynomial
生成逆向的数据位结果。实际上这是最常用的一个变体。 按照惯例,使用 CRC-32 多项式以及 CRC-16-CCITT 多项式时通常都要取反。CRC-32 的核验多项式是
C(x) = x31 + x30 + x26 + x25 + x24 + x18 + x15 + x14 + x12 + x11 + x10 + x8 + x6 + x5 + x4 + x3 + x + 1。
CRC 的错误检测能力依赖于关键多项式的阶次以及所使用的特定关键多项式。误码多项式 E(x) 是接收到的消息码字与正确消息码字的异或结果。当且仅当误码多项式能够被 CRC 多项式整除的时候 CRC 算法无法检查到错误。
。
如上所述,xk 不能被 CRC 多项式整除,它得到一个 xi ? k + 1 项。根据定义,满足多项式整除 xi ? k + 1 的 i ? k 最小值就是多项是的阶次。最高阶次的多项式是本原多项式,带有二进制系数的 n 阶多项式
下面的表格略去了“初始值”、“反射值”以及“最终异或值”。
CRC 标准化问题
名称 | 多项式 | 表示法:正常或者翻转 |
---|---|---|
CRC-1 | x + 1 (用途:硬件,也称为奇偶校验位) | 0x1 or 0x1 (0x1) |
CRC-5-CCITT | x5 + x3 + x + 1 (ITU G.704 标准) | 0x15 (0x??) |
CRC-5-USB | x5 + x2 + 1 (用途:USB 信令包) | 0x05 or 0x14 (0x9) |
CRC-7 | x7 + x3 + 1 (用途:通信系统) | 0x09 or 0x48 (0x11) |
CRC-8-ATM | x8 + x2 + x + 1 (用途:ATM HEC) | 0x07 or 0xE0 (0xC1) |
CRC-8-CCITT | x8 + x7 + x3 + x2 + 1 (用途:1-Wire 总线) | |
CRC-8-Dallas/Maxim | x8 + x5 + x4 + 1 (用途:1-Wire bus) | 0x31 or 0x8C |
CRC-8 | x8 + x7 + x6 + x4 + x2 + 1 | 0xEA(0x??) |
CRC-10 | x10 + x9 + x5 + x4 + x + 1 | 0x233 (0x????) |
CRC-12 | x12 + x11 + x3 + x2 + x + 1 (用途:通信系统) | 0x80F or 0xF01 (0xE03) |
CRC-16-Fletcher | 参见 Fletcher's checksum | 用于 Adler-32 A & B CRC |
CRC-16-CCITT | x16 + x12 + x5 + 1 (X25, V.41, Bluetooth, PPP, IrDA) | 0x1021 or 0x8408 (0x0811) |
CRC-16-IBM | x16 +x15 + x2 + 1 | 0x8005 or 0xA001 (0x4003) |
CRC-16-BBS | x16 + x15 + x10 + x3 (用途:XMODEM 协议) | 0x8408 (0x????) |
CRC-32-Adler | See Adler-32 | 参见 Adler-32 |
CRC-32-MPEG2 | See IEEE 802.3 | 参见 IEEE 802.3 |
CRC-32-IEEE 802.3 | x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 | 0x04C11DB7 or 0xEDB88320 (0xDB710641) |
CRC-32C (Castagnoli) | x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1 | 0x1EDC6F41 or 0x82F63B78 (0x05EC76F1) |
CRC-64-ISO | x64 + x4 + x3 + x + 1 (use: ISO 3309) | 0x000000000000001B or 0xD800000000000000 (0xB000000000000001) |
CRC-64-ECMA-182 | x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 + x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 + x10 + x9 + x7 + x4 + x + 1 (as described in ECMA-182 p.63) | 0x42F0E1EBA9EA3693 or 0xC96C5795D7870F42 (0x92D8AF2BAF0E1E85) |
CRC-128 | IEEE-ITU 标准。被 MD5 & SHA-1 取代 | |
CRC-160 | IEEE-ITU 标准。被 MD5 & SHA-1 取代 |
尽管在错误检测中非常有用,CRC 并不能可靠地验证数据完整性(即数据没有发生任何变化),这是因为 CRC 多项式是线性结构,可以非常容易地故意改变数据而维持 CRC 不变,参见CRC and how to Reverse it中的证明。我们可以用 Message authentication code 验证数据完整性。
与所有其它的散列函数一样,在一定次数的碰撞测试之后 CRC 也会接近 100% 出现碰撞。CRC 中每增加一个数据位,就会将碰撞数目减少接近 50%,如 CRC-20 与 CRC-21 相比。
生成多项式的选择是 CRC 算法实现中最重要的部分,所选择的多项式必须有最大的错误检测能力,同时保证总体的碰撞概率最小。多项式最重要的属性是它的长度,也就是最高非零系数的数值,因为它直接影响着计算的校验和的长度。
最常用的多项式长度有
在构建一个新的 CRC 多项式或者改进现有的 CRC 时,一个通用的数学原则是使用满足所有模运算不可分解多项式约束条件的多项式。
生成多项式的特性可以从算法的定义中推导出来:
总的分类
特殊技术参考
文章评论(0条评论)
登录后参与讨论