首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >adler32滚动校验和- python计算的差异

adler32滚动校验和- python计算的差异
EN

Stack Overflow用户
提问于 2012-03-14 09:40:13
回答 5查看 5.4K关注 0票数 1

在计算正在运行的校验和时,需要进行澄清。

假设我有这样的数据。

代码语言:javascript
复制
data = 'helloworld'

假设块大小为5,我需要计算运行校验和。

代码语言:javascript
复制
>>> zlib.adler32('hello')
103547413
>>> zlib.adler32('ellow')
105316900

根据Python文档(python版本2.7.2)

代码语言:javascript
复制
zlib.adler32(data[, value])

“计算数据的Adler-32校验和。( Adler-32校验和几乎与CRC32一样可靠,但可以更快地计算。)如果存在值,则将其用作校验和的起始值;否则,将使用固定的默认值。这允许在连接多个输入时计算正在运行的校验和。”

但当我提供这样的东西时,

代码语言:javascript
复制
>>> zlib.adler32('ellow', zlib.adler32('hello'))
383190072

输出完全不同。

我尝试创建一个自定义函数来生成rsync算法中定义的滚动校验和。

代码语言:javascript
复制
def weakchecksum(data):
    a = 1
    b = 0

    for char in data:
        a += (ord(char)) % MOD_VALUE
        b += a % MOD_VALUE



    return (b << 16) | a



def rolling(checksum, removed, added, block_size):
    a = checksum
    b = (a >> 16) & 0xffff
    a &= 0xffff

    a = (a - ord(removed) + ord(added)) % MOD_VALUE
    b = (b - (block_size * ord(removed)) + a) % MOD_VALUE

    return (b << 16) | a

以下是运行这些函数所得到的值

代码语言:javascript
复制
Weak for hello: 103547413
Rolling for ellow: 105382436
Weak for ellow: 105316900

正如您所看到的,在我实现滚动校验和和与python的实现方面,在价值方面有一些巨大的差异。

我在计算滚动校验和时出了什么问题?我是否正确地利用python的adler32函数的滚动特性?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-03-14 19:17:33

adler32()函数不提供“滚动”。文档正确地使用了“运行”(而不是“滚动”)这个词,这意味着它可以以块的形式计算adler32,而不是一次计算全部。您需要编写自己的代码来计算“滚动”adler32值,这将是数据上方滑动窗口的adler32。

票数 7
EN

Stack Overflow用户

发布于 2013-11-20 02:25:51

在您的方法“滚动”中,

代码语言:javascript
复制
b = (b - (block_size * ord(removed)) + a) % MOD_VALUE

应该是

代码语言:javascript
复制
b = (b - (block_size * ord(removed)) + a - 1) % MOD_VALUE

根据维基百科对adler32算法的解释,我们可以看到:

代码语言:javascript
复制
A = 1 + D1 + D2 + ... + Dn (mod 65521)
B = (1 + D1) + (1 + D1 + D2) + ... + (1 + D1 + D2 + ... + Dn) (mod 65521)
  = n×D1 + (n−1)×D2 + (n−2)×D3 + ... + Dn + n (mod 65521)

Adler-32(D) = B × 65536 + A

当我们滚动校验和时,我们将得到这样的方程:

代码语言:javascript
复制
A1 = (1 + D2 + D3 + … + Dn + Dn+1)(mod 65521)
= (1 + D1 + D2 + D3 + … + Dn) – D1 + Dn+1(mod 65521)
= A – D1 + Dn+1(mod 65521)
B1 = (1 + D2) + (1 + D2 + D3) + … + (1 + D2 + D3 + … + Dn + Dn+1)(mod 65521)
= (1 + D1) – D1 – 1 + (1 + D1 + D2) – D1 + ... +(1 + D1 + D2 + … + Dn) – D1 + (1 + D1 + D2 +      … + Dn + Dn+1) – D1(mod 65521)
= B – nD1 – 1 + A1 + D1 – D1(mod 65521)
= B – nD1 + A1 – 1(mod 65521)
票数 5
EN

Stack Overflow用户

发布于 2012-03-15 18:32:45

顺便说一句,def ()是正确的,至少对于Python来说,在Python中,模块化结果的符号带有除数符号。它在其他语言中可能不起作用,例如,在C语言中,%的结果符号要么是派息的符号,要么是定义的实现。

您可以通过考虑在每一步中距离模块65521有多远,或者用if和增减65521替换%,或者使用足够大的数据类型让它持续一段时间,并计算出在总和上获得%以避免溢出的情况,从而提高算法的效率。同样,在负红利问题上要小心。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9699315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档