Ожидаемый результат
То, что вы ожидаете, обычно является тем, чего вы должны ожидать от обычных криптографических библиотек.В большинстве криптографических библиотек хеш-объект сбрасывается после вызова метода, который завершает вычисление , например hexdigest
.Кажется, что hashlib.md5
использует альтернативное поведение.
Результат по hashlib.md5
MD5 требует, чтобы вход был дополнен 1
битом, нулем или более 0
битами идлина ввода в битах.Затем вычисляется окончательное значение хеша.hashlib.md5
внутренне, кажется, выполняет окончательное вычисление, используя отдельные переменные, сохраняя состояние после хэширования каждой строки без этого окончательного заполнения.
Таким образом, результатом ваших хэшей является объединение более ранних строк с данной строкой,с последующим правильным заполнением, как duskwulf указал в своем ответе .
Это правильно задокументировано hashlib:
hash.digest()
Возвращает дайджест строк, переданных в метод update()
до сих пор .Это строка из digest_size
байтов, которая может содержать не-ASCII-символы, включая нулевые байты.
и
hash.hexdigest()
Как и digest()
, за исключением того, что дайджест возвращается в виде строки двойной длины, содержащей только шестнадцатеричные цифры.Это может быть использовано для безопасного обмена значениями в электронной почте или других недвоичных средах.
Решение для hashlib.md5
Поскольку там не кажетсячтобы быть reset()
методом , вы должны создать новый объект md5
для каждого отдельного хеш-значения, которое вы хотите создать.К счастью, сами хеш-объекты относительно легки (даже если само хеширование не выполняется), поэтому это не потребляет много ресурсов ЦП или памяти.
Обсуждение различий
Для сброса самого хэшированияхеш в финализаторе может не иметь особого смысла.Но это имеет значение для генерации подписи: вы можете инициализировать один и тот же экземпляр подписи, а затем создать несколько подписей с ним.Хэш-функция должна быть сброшена, чтобы она могла вычислять сигнатуру для нескольких сообщений.
Иногда приложению требуется объединенный хэш для нескольких входов, включая промежуточные результаты хеширования.В этом случае, однако, используется дерево Меркля хешей, где сами промежуточные хеши снова хэшируются.
Как указано, я считаю, что это плохой дизайн API авторами hashlib.Для криптографов это, конечно, не следует правилу наименьшего удивления.