Почему хэш-функция Python не дает одинаковые значения при запуске в реализации Android? - программирование
Подтвердить что ты не робот

Почему хэш-функция Python не дает одинаковые значения при запуске в реализации Android?

Я считал, что функция hash() работает одинаково во всех интерпретаторах python. Но он отличается тем, что я запускаю его на своем мобильном телефоне, используя python для android. Я получаю одно и то же значение хеширования для хеширующих строк и чисел, но когда у меня есть встроенные типы данных, значение хеша отличается.

Интерпретатор Python для ПК (Python 2.7.3)

>>> hash(int)
31585118
>>> hash("hello sl4a")
1532079858
>>> hash(101)
101

Мобильный Python Interpreter (Python 2.6.2)

>>> hash(int)
-2146549248
>>> hash("hello sl4a")
1532079858
>>> hash(101)
101

Может ли кто-нибудь сказать мне, что это ошибка, или я что-то не понял.

4b9b3361

Ответ 1

для старого python (по крайней мере, моего Python 2.7), кажется, что

hash(<some type>) = id(<type>) / 16

а для CPython id() - адрес в памяти - http://docs.python.org/2/library/functions.html#id

>>> id(int) / hash(int)                                                     
16                                                                              
>>> id(int) % hash(int)                                                 
0                                                                               

поэтому я предполагаю, что у порта Android есть странное соглашение для адресов памяти?

в любом случае, учитывая выше, хеши для типов (и другие встроенные модули, которые я предполагаю) будут различаться между установками, потому что функции находятся на разных адресах.

напротив, хеши для значений (что, я думаю, вы подразумеваете под "не-внутренними объектами" ) (до того, как был добавлен случайный материал), рассчитываются по их значениям и, следовательно, могут повторяться.

PS, но там, по крайней мере, еще одна морщина CMython:

>>> for i in range(-1000,1000):
...     if hash(i) != i: print(i)
...
-1

там ответ здесь где-то объясняет, что один...

Ответ 2

hash() рандомизируется по умолчанию каждый раз, когда вы запускаете новый экземпляр последних версий (Python3.3 +) на предотвращать вставку DOS в словарях

До этого hash() отличался для 32-битной и 64-битной сборки в любом случае.

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

>>> import hashlib
>>> hashlib.algorithms
('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')

Ответ 3

Хеширование таких вещей, как int, зависит от id(), которое не гарантируется постоянной между прогонами или между интерпретаторами. То есть, hash (int) всегда будет давать одинаковый результат во время прогона программы, но не может сравниться с равными между прогонами, либо на одной платформе, либо на разных платформах.

BTW, а хэш-рандомизация доступна в Python, она по умолчанию отключена. Поскольку ваши строки и числа хэшируются одинаково, ясно, что это не проблема здесь.

Ответ 4

С CPython по соображениям эффективности hash() для внутренних объектов возвращается то же значение, что и id(), которые, в свою очередь, возвращают место памяти ( "адрес" ) объекта.

От одного интерпретатора на основе CPython до другого местоположения памяти такого объекта могут быть изменены. В зависимости от вашей ОС это может меняться от одного запуска к другому.

Ответ 5

Начиная с Python 3.3 алгоритм хеширования по умолчанию создает хеш-значения со случайным значением, которое отличается даже в разных процессах python на одном компьютере.

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

Один и тот же frozenset последовательно выдает одинаковое значение хеш-функции на разных машинах или даже на разных процессах.

Источник: https://www.quora.com/Do-two-computers-produce-the-same-hash-for-identical-objects-in-Python