Подтвердить что ты не робот

Является ли встроенный хэш-метод Python2.6 стабильным по архитектуре?

Мне нужно вычислить хэш, который должен быть стабильным в разных архитектурах. Является ли python hash() стабильным?

Чтобы быть более конкретным, в приведенном ниже примере показано, что hash() вычисляет одно и то же значение на двух разных хостах/архитектурах:

# on OSX based laptop
>>> hash((1,2,3,4))
485696759010151909
# on x86_64 Linux host
>>> hash((1,2,3,4))
485696759010151909

Вышеприведенное верно для хотя бы этих входов, но мой вопрос касается общего случая

4b9b3361

Ответ 1

Если вам нужен четко определенный хэш, вы можете использовать один из hashlib.

Ответ 2

Функция 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 для любой реализации, на которую вы полагаетесь.

Ответ 3

Нет.

x86_64
>>> print hash("a")
12416037344

i386
>>> print hash("a")
-468864544

Если вам нужен стабильный хеш, создайте дайджест ваших данных, используя что-то вроде sha1, которое можно найти в hashlib

Ответ 4

Нет. На ARM с python 2.6:

>>> hash((1,2,3,4)) 

89902565