実行中のチェックサムの計算を検討する際には、説明が必要です。
このようなデータがあると仮定します。
data = 'helloworld'
ブロックサイズを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
これらの関数を実行して得られる値は次のとおりです
Weak for hello: 103547413
Rolling for ellow: 105382436
Weak for ellow: 105316900
ご覧のとおり、ローリングチェックサムとPythonの実装には、価値の点で大きな違いがあります。
ローリングチェックサムの計算でどこが間違っているのですか?Pythonのadler32関数のローリングプロパティを正しく利用していますか?