能力值:
( LV12,RANK:240 )
|
-
-
2 楼
(我解不了你的疑,但我可以给你一个起点,如果你最终能解答我的那个疑问,务必请你教一下我,先谢过)
Ross N. Williams写过一份非常棒的文档([1])介绍CRC(Cyclic Redundancy Code)原
理。CRC的基本思路是多项式长除法。
先回忆一下小学数学中的10进制长除法:
77
+------
74 ) 5751
518
---
571
518
---
53
被除数 : 5751
除数 : 74
商 : 77
余数 : 53
与之类似的2进制长除法如下:
10101101
+------------------
1001 ) 11000010111
1001
----
0110
0000
----
1100
1001
----
0111
0000
----
1110
1001
----
1011
1001
----
0101
0000
----
1011
1001
----
010
被除数 : 11000010111 : 1519
除数 : 1001 : 9
商 : 10101101 : 173
余数 : 010 : 2
将2进制长除法过程中的"借位减法运算"换成"不借位的异或运算",就是传说中的多
项式长除法:
1011
+---------
1101 ) 1111111
1101
----
0101
0000
----
1011
1101
----
1101
1101
----
000
被除数 : 1111111
除 数 : 1101
商 : 1011
余 数 : 000
换个方式抽象表述上面这些数字(^表示乘方):
被除数 : x^6 + x^5 + x^4 + x^3 + x^2 + x^1 + x^0
除 数 : x^3 + x^2 + x^0
商 : x^3 + x^1 + x^0
余 数 : 0
看得出,0/1对应了多项式各次项的系数。最终的多项式长除法如下:
x^3 + x^1 + x^0
+-----------------------------------------
x^3 + x^2 + x^0 ) x^6 + x^5 + x^4 + x^3 + x^2 + x^1 + x^0
x^6 + x^5 + x^3
---------------
x^4 + x^2 + x^1 + x^0
x^4 + x^3 + x^1
---------------
x^3 + x^2 + x^0
x^3 + x^2 + x^0
---------------
0
多项式长除法的实质是对各次项系数做模2减法,注意-1模2后是1。这种模2减法就是
异或运算。
原始数据 : 1101011011
除数 : 10011(生成多项式,5个2进制位)
被除数 : 11010110110000(在原始数据后添加0,0的个数比除数的2进制位数少1)
进行多项式长除法运算:
1100001010
+----------------
10011 ) 11010110110000
10011
-----
10011
10011
-----
00001
00000
-----
00010
00000
-----
00101
00000
-----
01011
00000
-----
10110
10011
-----
01010
00000
-----
10100
10011
-----
01110
00000
-----
1110 <= CRC
原始数据 : 1101011011
除数 : 10011(生成多项式,5个2进制位)
被除数 : 11010110110000(在原始数据后添加0,0的个数比除数的2进制位数少1)
商 : 1100001010(我们不关心商)
余数 : 1110(针对原始数据的CRC)
最终数据 : 11010110111110(原始数据+CRC)
如何选择生成多项式是个学问,对于我们来说,无需关心数学理论问题,下面是一些
现实世界使用的生成多项式:
X25 : x^16 + x^12 + x^5 + x^0
: (16,12,5,0)
CRC-16 : x^16 + x^15 + x^2 + x^0
: (16,15,2,0)
Ethernet : x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0
: (32,26,23,22,16,12,11,10,8,7,5,4,2,1,0)
CRC算法的优化实现对我来说比较晦涩,大学学的东西早已还给老师,故就不误人子
弟似的在此介绍CRC算法优化背后的数学原理了。Sven Reifegerste提供了一份精彩
的C代码,演示了四种实现([11])。
> CRC32 "1314"
Plain : 31 33 31 34
CRC32 : 0xA817E816
CRC32.c算出来的CRC32值与很多现成工具算出来的相一致。试图手工进行多项式长除
法得到这个结果,但总是得不到。很想知道如何通过多项式长除法得到结果,就算是
涉及一些二进制位的反序处理,也给我一个针对"\x31\x33\x31\x34"的手工计算例子
吧。可惜天下文章一大抄,没找到可答疑解惑的文章。
[ 1] A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS
http://www.repairfaq.org/filipg/LINK/F_crc_v31.html
http://www.repairfaq.org/filipg/LINK/F_crc_v32.html
http://www.repairfaq.org/filipg/LINK/F_crc_v33.html
http://www.repairfaq.org/filipg/LINK/F_crc_v34.html
http://www.repairfaq.org/filipg/LINK/F_crc_v35.html
(前半截讲解的非常清楚,后半截还是比较晦涩)
[11] http://www.gpfn.sk.ca/~rhg/csc8550s02/crctester.c(cool)
http://zorc.breitbandkatze.de/crctester.c
|
能力值:
( LV12,RANK:240 )
|
-
-
3 楼
http://bbs.pediy.com/showthread.php?t=40938
|
能力值:
( LV12,RANK:240 )
|
-
-
4 楼
楼上这位,请教你一个问题。
原始数据"\x31\x33\x31\x34",我想知道如何通过"手工"多项式长除法得到数值
0xA817E816。
能给个原理性"手工"演示吗?多谢。
BTW,如果是那些个现成的C、ASM代码,就不必给了,全干过。
|
能力值:
( LV2,RANK:10 )
在线值:
|
-
-
5 楼
看过还不是很明白的!
|
|
|