Ответ 1
Если вам нужен четко определенный хэш, вы можете использовать один из hashlib.
Мне нужно вычислить хэш, который должен быть стабильным в разных архитектурах. Является ли python hash() стабильным?
Чтобы быть более конкретным, в приведенном ниже примере показано, что hash() вычисляет одно и то же значение на двух разных хостах/архитектурах:
# on OSX based laptop
>>> hash((1,2,3,4))
485696759010151909
# on x86_64 Linux host
>>> hash((1,2,3,4))
485696759010151909
Вышеприведенное верно для хотя бы этих входов, но мой вопрос касается общего случая
Если вам нужен четко определенный хэш, вы можете использовать один из hashlib.
Функция hash()
не то, что вы хотите; найти надежный способ сериализации объекта (например, str()
или repr()
) и запустить его через hashlib.md5()
, вероятно, будет гораздо более предпочтительным.
Подробно - hash()
предназначен для возврата целого числа, которое однозначно идентифицирует объект только в течение его жизни. Как только программа запускается снова, построение нового объекта может иметь другой хеш. Уничтожение объекта означает, что в будущем у другого объекта будет этот хеш. Подробнее см. Определение python hashable.
За кулисами большинство пользовательских объектов python возвращаются к id()
, чтобы предоставить их значение хэша. Хотя вы не должны использовать это, id(obj)
и, следовательно, hash(obj)
обычно реализуется (например, в CPython) в качестве адреса памяти базового объекта Python. Таким образом, вы можете понять, почему на что нельзя положиться.
Поведение, которое вы сейчас видите, является надежным только для определенных встроенных объектов python, и это не очень далеко. hash({})
, например, невозможно.
Относительно hashlib.md5(str(obj))
или эквивалента - вам нужно убедиться, что str(obj)
надежно одинаков. В частности, если у вас есть перевод словаря внутри этой строки, он может не перечислить его ключи в том же порядке. Также могут быть тонкие различия между версиями python... Я бы определенно рекомендовал unittests для любой реализации, на которую вы полагаетесь.
Нет.
x86_64
>>> print hash("a")
12416037344
i386
>>> print hash("a")
-468864544
Если вам нужен стабильный хеш, создайте дайджест ваших данных, используя что-то вроде sha1, которое можно найти в hashlib
Нет. На ARM с python 2.6:
>>> hash((1,2,3,4))
89902565