Я реализую в версии rolling версию adler32 checksum.Почему моя текущая контрольная сумма adler32 не работает? (по модулю арифметики)
Это answer было полезно дважды проверить мои математические данные. Однако я стараюсь правильно ее внедрить в 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
}
тестировал его на различные входы и она работала хорошо, пока я не решил запустить его на случайных данных. Вот sample, где он не работает (я нашел несколько из них).
Что озадачивает меня в том, что тот же самый код в питоне отлично работает на этих входах:
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
Для хорошей меры, я в том числе proof, что это работает в питоне. Обратите внимание, что контрольная сумма python соответствует некалиберной версии контрольной суммы go (и эта часть находится непосредственно из основных библиотек go).
Я изучил свои результаты по всем другим проблемным образцам и обнаружил, что я никогда не ошибаюсь в младших значащих бит контрольной суммы (бит «а»). Кроме того, ошибка постоянно одинакова, равна 0xe10000
. Я подозреваю, что причиной того, как go обрабатывает по модулю операции с целыми числами uint32, является причиной этого.
Что происходит и как я могу исправить свой код?
Ваше вычитание обертывается. – user2357112
Как вы исправите код? – user48678
Вы получаете такое же несоответствие (0xe10000) в коде Python, если вы применяете 32-битную маску при вычислении b следующим образом: 'b = ((b - (n * leave) - 1 + a) & 0xffffffff)% MOD ' – samgak