Несовместимый вывод ha sh для кортежей - PullRequest
3 голосов
/ 17 апреля 2020

Сравнение га sh es для некоторых двухэлементных кортежей

for i in range(11):
    print(i, hash((i,i)) == hash((-i,-i)))

Я ожидал получить True для i==0 и False для остальных. Я был удивлен, увидев это:

0 True
1 False
2 True
3 True
4 True
5 True
6 True
7 True
8 False
9 True
10 True

Почему это происходит?

AFAIK это не та же проблема, что и в этом вопросе, поскольку речь идет не о порядке но сами ценности.

Ответы [ 2 ]

3 голосов
/ 17 апреля 2020
Значения

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

Отрывок из список изменений для Python 3.8.0 alpha 1 :

bpo-34751 : функция ha sh для кортежей теперь основана на xxHa sh, который дает лучшие результаты столкновений в (ранее) патологических случаях. Кроме того, в 64-битных системах это улучшает хеши кортежей в целом. Патч от Jeroen Demeyer с существенным вкладом Tim Peters.

0 голосов
/ 18 апреля 2020

Для дальнейшего использования я использовал этот код для согласованного хеширования кортежей:

import hashlib
import pickle

def hash2(data):
    bytez = pickle.dumps(data)
    hashed = hashlib.md5(bytez)
    return int(hashed.hexdigest(), 16)
...