Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
adler32滚动校验和-python计算的差异_Python_Adler32 - Fatal编程技术网

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

adler32滚动校验和-python计算的差异,python,adler32,Python,Adler32,在计算运行校验和时需要澄清 >>> zlib.adler32('hello') 103547413 >>> zlib.adler32('ellow') 105316900 假设我有这样的数据 data = 'helloworld' 假设blocksize为5,我需要计算运行校验和 >>> zlib.adler32('hello') 103547413 >>> zlib.adler32('ellow') 105316900

在计算运行校验和时需要澄清

>>> zlib.adler32('hello')
103547413
>>> zlib.adler32('ellow')
105316900
假设我有这样的数据

data = 'helloworld'
假设blocksize为5,我需要计算运行校验和

>>> zlib.adler32('hello')
103547413
>>> zlib.adler32('ellow')
105316900
根据Python文档Python版本2.7.2

zlib.adler32(data[, value])
计算数据的Adler-32校验和。Adler-32校验和几乎是 与CRC32一样可靠,但计算速度更快。如果 值存在时,将其用作校验和的起始值; 否则,将使用固定的默认值。这允许计算 在多个输入的串联上运行校验和

但当我提供这样的东西时

>>> zlib.adler32('ellow', zlib.adler32('hello'))
383190072
结果完全不同

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

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
正如您所看到的,我的滚动校验和实现与python的实现在价值上有很大的不同

我在计算滚动校验和时哪里出错了?
我是否正确地使用了python的adler32函数的滚动特性?

我相信您在测试中错误地计算了adler32值:

>>> import zlib
>>> zlib.adler32("helloworld")
389415997
>>> zlib.adler32("world",zlib.adler32("hello"))
389415997

我相信您在测试中错误计算了adler32值:

>>> import zlib
>>> zlib.adler32("helloworld")
389415997
>>> zlib.adler32("world",zlib.adler32("hello"))
389415997

adler32功能不提供滚动。文档正确地使用了running not rolling这个词,这意味着它可以分块计算adler32,而不是一次计算所有adler32。您需要编写自己的代码来计算滚动adler32值,该值将是数据上滑动窗口的adler32。

adler32函数不提供滚动。文档正确地使用了running not rolling这个词,这意味着它可以分块计算adler32,而不是一次计算所有adler32。您需要编写自己的代码来计算滚动adler32值,这将是数据上滑动窗口的adler32。

顺便说一句,您的def滚动是正确的,至少在Python中,模结果的符号有除数的符号。它可能在其他语言中不起作用,例如,在C语言中,%的结果的符号是红利的符号,或者是实现定义的符号


您可以通过考虑在每一步中距离模65521有多远来提高算法的效率,或者用if和65521的加减来替换%,或者使用足够大的数据类型让它保持一段时间,并计算出在求和中不使用%以避免溢出的频率。同样,要注意负红利的%。

顺便说一句,您的def滚动是正确的,至少在Python中,模结果的符号有除数的符号。它可能在其他语言中不起作用,例如,在C语言中,%的结果的符号是红利的符号,或者是实现定义的符号


您可以通过考虑在每一步中距离模65521有多远来提高算法的效率,或者用if和65521的加减来替换%,或者使用足够大的数据类型让它保持一段时间,并计算出在求和中不使用%以避免溢出的频率。同样,要注意负红利的百分比。

这里是工作函数。请注意MOD的计算步骤

def myadler32(data):
  a = 1
  b = 0
  for c in data:
      a += c
      b += a
  a %= MOD_ADLER
  b %= MOD_ADLER
  return b<<16 | a

这里是工作函数。请注意MOD的计算步骤

def myadler32(data):
  a = 1
  b = 0
  for c in data:
      a += c
      b += a
  a %= MOD_ADLER
  b %= MOD_ADLER
  return b<<16 | a

在您的滚动方法中

b = (b - (block_size * ord(removed)) + a) % MOD_VALUE
应该是

b = (b - (block_size * ord(removed)) + a - 1) % MOD_VALUE
根据维基百科对算法的解释,我们可以看到:

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
当我们进行滚动校验和时,我们将得到以下等式:

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)

在您的滚动方法中

b = (b - (block_size * ord(removed)) + a) % MOD_VALUE
应该是

b = (b - (block_size * ord(removed)) + a - 1) % MOD_VALUE
根据维基百科对算法的解释,我们可以看到:

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
当我们进行滚动校验和时,我们将得到以下等式:

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)

谢谢但是,我想我是在寻找滚动校验和的差异。在你的例子中,我得到的是'world'的校验和,我感兴趣的是,用'hello'的校验和计算'ellow'的校验和。两者之间的区别在于删除了“h”,添加了“w”。如果我不清楚,请告诉我。谢谢。但是,我想我是在寻找滚动校验和的差异。在你的例子中,我得到的是'world'的校验和,我感兴趣的是,用'hello'的校验和计算'ellow'的校验和。两者之间的区别在于删除了“h”,添加了“w”。如果我不清楚,请告诉我。马克,谢谢你的补充意见。我尝试使用prime 65521,但在我的滚动校验和过程实现中出现了计算错误。检测到或未检测到更改。如果我使用2^16,一切都很好。我希望稍后能够回到这个问题上来,排除编程错误的可能性,同时带来一些关于这个主题的有用信息。马克,谢谢你的补充意见。我尝试了prime 65521,但在我的 滚动校验和过程实现检测到或未检测到更改。如果我使用2^16,一切都很好。我希望稍后能够回到这个问题上来,同时排除编程错误的可能性,带来一些关于这个主题的有用信息。