Постоянное хэширование замороженных наборов Python - PullRequest
5 голосов
/ 27 декабря 2011

Как бы вы преобразовали вложенность объектов Python frozenset в уникальное целое число, которое было одинаковым для сеансов и платформ Python?

например, я получаю разные значения из hash () на разных платформах

32-битный

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=frozenset([frozenset([1,2,3]),frozenset(['a','b','c'])]);
>>> hash(a)
1555175235

64-битный

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=frozenset([frozenset([1,2,3]),frozenset(['a','b','c'])]);
>>> hash(a)
-6076998737938213053

Ответы [ 2 ]

8 голосов
/ 27 декабря 2011

Как бы вы преобразовали вложенность объектов Python frozenset в уникальное целое число, которое было одинаковым для сеансов и платформ Python?

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

Это сказал. Если вам нужен непротиворечивый, неуникальный «хеш» для разных платформ, я бы попытался использовать стандартную библиотеку hashlib . У меня нет возможности попробовать его на другой платформе, но я считаю, что большинство реализованных там алгоритмов (например, MD5) не зависят от платформы.

Я бы снабдил алгоритмы хеширования маринованной версией отсортированного набора, чтобы убедиться, что строка, используемая для хеширования, всегда одинакова.


РЕДАКТИРОВАТЬ: Мысль добавить базовый пример:

>>> import cPickle as pkl
>>> import hashlib as hl
>>> s = frozenset([1,2,3])
>>> p = pkl.dumps(sorted(s))  #make sure you use the same pickle protocol on all platform!
'(lp1\nI1\naI2\naI3\na.'
>>> h = hl.md5(p)
<md5 HASH object @ 0xb76fb110>
>>> h.digest()
"\x89\xaeG\x1d'\x83\xa5\xbd\xac\xa7\x1c\xd9\x1d/2t"  #this should be consistent
0 голосов
/ 27 декабря 2011

Вы также можете создать свою собственную хеш-функцию:

def hash(fs):
    res = 1
    for v in fs:
        res = (res*31 + v) % 2**30
    return res

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...