adler32 checksumのローリングバージョンを実装しています。
この回答は、私の数学を再確認するのに役立ちました。ただし、golang で正しく実装するのに苦労しています。
次のコードを書きました。
func roll(adler, n, leave, enter uint32) uint32 {
a := adler & 0xffff
b := adler >> 16
a = (a + enter - leave) % MOD
b = (b - n*leave - 1 + a) % MOD
return b<<16 | a
}
ランダムなデータで実行することを決定するまで、さまざまな入力でテストし、正常に機能しました。これが機能しないサンプルです(いくつか見つけました)。
私を困惑させているのは、Pythonの同じコードがこれらの入力で完全に機能することです:
def roll(adler, n, leave, enter):
a = adler & 0xffff
b = adler >> 16
a = (a + enter - leave) % MOD
b = (b - n*leave - 1 + a) % MOD
return b<<16 | a
念のため、これが Python で機能することの証明を含めます。Python チェックサムは、go チェックサムの非ローリング バージョンと一致することに注意してください (その部分は、go コア ライブラリから直接取得されます)。
問題のある他のすべてのサンプルで結果を調べたところ、チェックサムの最下位ビット (「a」ビット) を決して間違えていないことがわかりました。また、エラーは一貫して同じで、 に等しくなり0xe10000
ます。go が uint32 整数の剰余演算を処理する方法の特殊性が、この原因であると思われます。
何が起こっているのか、コードを修正するにはどうすればよいですか?