-
-
[原创]小议Fletcher's checksum
-
发表于:
2006-9-20 19:58
11158
-
[原创]小议Fletcher's checksum
将一些标准或实现语焉不详的地方或难于理解的地方说清楚,不希望有任何死角。
欢迎大牛指正。
By:TnTTools
:::参数集合:::
Parameter Set
利用参数集合来描述具体的算法,是我从Ross处得到的灵感。
http://www.ross.net/crc/
Name
Chksum(LengthA+LengthB)
Block
InitA, InitB
Modulo(Base)
Name
算法的名字,一般是约定俗成的,可不是我随意起的。
Block指处理单元(块)的长度。
8-bit可用于处理ANSI字符,16-bit可用于处理Unicode字符。
标准中8-bit Fletcher, 16-bit Fletcher
就是指此参数。
Chksum指校验和的长度。
A和B的长度一般相同:LengthA=LengthB=Chksum/2。
Adler-8, Adler-16, Adler-32
其中的数字8,16,32就是指此参数。
InitA,InitB
A和B的初始化值
Modulo(Base)
模,Base见于adler32.c in zlib
一般地Fletcher's checksum的模是65535;
而Adler's checksum的模变为65521.
Name: Adler-32
ChkSum: 32(LengthA,LengthB: 16)
InitB,InitA: 0x0000, 0x0001
Modulo: 65521
:::数学原理:::
Fletcher's 的数学原理非常简单:和,数列的和。
; original
A = Sum.
B = Sum of sum.
; More practical
A = InitA + D[1] + D[2] + D[3] + ... + D[n]
B = InitB + nInitA + nD[1] + (n-1)D[2] + (n-2)D[3] + ... + D[n]
:::实现:::
RFC1146中的实现太过简略,没有实用价值。
实用的代码,可参见
Fletcher's
ttp://en.wikipedia.org/wiki/Fletcher%27s_checksum
Adler's
(1)
adler32.c
(2)
ttp://en.wikipedia.org/wiki/Adler-32
外循环遍历字符数列,内循环实现不溢出条件下的具体加法操作。
下面说明一下360和5552这两个数字的来历。
:::360:::
360是...算法中A和B都不会溢出时内循环最大次数N的最大整数值。
Block=16,Chksum=32, Modulo=65535
<h>推导过程</h>
B和A执行相同次数的加法操作,B明显比A大
只要B不溢出,A也不会溢出。
B = InitB + N*InitA + N*D[1]+(N-1)*D[2]+(N-2)*D[3]+...+D[N]
MaxD[x]=0x0000FFFF,
MaxInitA=Modulo-1=0x0000FFFF
MaxInitB=Modulo-1=0x0000FFFF
B(max) = 0x0000FFFF * N * (N+1)/2 + (N+1)* 0x0000FFFF
B(max) <= 0xFFFFFFFF
解不等方程式:
0xFFFFFFFF >= 0x0000FFFF * N * (N+1)/2 + (N+1)* 0x0000FFFF
<=>
N*N + 3N - (65537-1)*2 <= 0
N*N + 3N - 131072 <= 0
解得:
-363.54 <= N <= +360.54
:::5552:::
5552是...算法中A和B都不会溢出时内循环最大次数N的最大整数值。
Block=8, Chksum=32, Modulo=65535
<h>推导过程</h>
B = InitB + N*InitA + N*D[1]+(N-1)*D[2]+(N-2)*D[3]+...+D[N]
MaxD[x]=0x000000FF
MaxInitA=Modulo-1=0x0000FFFF
MaxInitB=Modulo-1=0x0000FFFF
B(max) = 0x000000FF * N * (N+1)/2 + (N+1)* 0x0000FFFF
B(max) <= 0xFFFFFFFF
解不等方程式:
0xFFFFFFFF >= 0x000000FF * N * (N+1)/2 + (N+1)* 0x0000FFFF
<=>
N*N + (1+0x202)N <= ( 0x1010101 - 0x101 )*2
N*N + 515*N <= 33685504
解得:
-6067.13 <= N <= + 5552.13
::组合::
如果有两个Fltecher's checksum,如何组合它们。相关的数学原理为
A1 = InitA + P[1] + P[2] + ... + P[m]
B1 = InitB + mInitA + mP[1] + (m-1)P[2] + ... + P[m]
A2 = InitA + Q[1] + Q[2] + ... + Q[n]
B2 = InitB + nInitA + nQ[1] + (n-1)Q[2] + ... + Q[n]
A = InitA + P[1] + ... + P[m] + Q[1] + ... + Q[n]
= A1 + A2 - InitA
B = InitB + (m+n)InitA + (m+n)P[1] + ... + (1+n)P[m] + nQ[1] + ... + Q[n]
= B1 + B2 + n*(A1 - InitA) - InitB
adler32的实现代码可参见adler32_combine() in adler32.c in zlib 1.2.3.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!