Python использует случайное начальное число хеша, чтобы злоумышленники не смогли запятнать ваше приложение, отправив вам ключи, предназначенные для конфликтов. См. Исходное сообщение об уязвимости . Заменяя хеш случайным начальным значением (установленным один раз при запуске), злоумышленники больше не могут предсказать, какие ключи будут конфликтовать.
Вы можете установить фиксированное начальное число или отключить эту функцию, установив PYTHONHASHSEED
переменную среды ; по умолчанию используется, random
но вы можете установить для него фиксированное положительное целое число, полностью 0
отключив эту функцию.
В версиях Python 2.7 и 3.2 эта функция отключена по умолчанию (используйте -R
переключатель или установите, PYTHONHASHSEED=random
чтобы включить ее); он включен по умолчанию в Python 3.3 и выше.
Если вы полагались на порядок ключей в наборе Python, то не стоит. Python использует хеш-таблицу для реализации этих типов, и их порядок зависит от истории вставки и удаления, а также от случайного начального числа хеша. Обратите внимание, что в Python 3.5 и старше это относится и к словарям.
Также см. object.__hash__()
Документацию по специальному методу :
Примечание . По умолчанию __hash__()
значения объектов str, bytes и datetime «подсолены» с непредсказуемым случайным значением. Хотя они остаются постоянными в рамках отдельного процесса Python, их нельзя предсказать между повторными вызовами Python.
Это предназначено для обеспечения защиты от отказа в обслуживании, вызванного тщательно подобранными входными данными, которые используют наихудшую производительность вставки dict, сложность O (n ^ 2). Подробнее см. Http://www.ocert.org/advisories/ocert-2011-003.html .
Изменение значений хеш-функции влияет на порядок итерации dicts, множеств и других отображений. Python никогда не давал гарантий относительно этого порядка (и обычно он варьируется между 32-битными и 64-битными сборками).
См. Также PYTHONHASHSEED
.
Если вам нужна стабильная реализация хеширования, вы, вероятно, захотите взглянуть на hashlib
модуль ; это реализует криптографические хеш-функции. Проект pybloom использует этот подход .
Поскольку смещение состоит из префикса и суффикса (начальное значение и конечное значение XOR), к сожалению, вы не можете просто сохранить смещение. С другой стороны, это означает, что злоумышленники не могут легко определить смещение с помощью временных атак.
disable
при установке на 0? Я не вижу эффективной разницы в установке любого старого стабильного начального числа, если я чего-то не упускаю. Я имею в виду, что когда я использую,PYTHONHASHSEED=12345
я получаю один и тот же хеш для одинаковых строк даже в разных сеансах - то же самое происходит, когда я используюPYTHONHASHSEED=0
- хеш для одинаковых строк будет одинаковым для всех сеансов (хотя и отличается от 12345, но это очевидно, вот как семена Работа).0
здесь нет семени вообще, а хэши для объектов идентичны тем, которые были сгенерированы в более старой версии Python без какой-либо поддержки хэша.Рандомизация хэша включена по умолчанию в Python 3 . Это функция безопасности:
В предыдущих версиях, начиная с 2.6.8, вы могли включить его в командной строке с помощью -R или параметра среды PYTHONHASHSEED .
Вы можете выключить его, установив
PYTHONHASHSEED
на ноль.источник
hash () - это встроенная функция Python, которая используется для вычисления хеш-значения для объекта , а не для строки или числа.
Подробности можно увидеть на этой странице: https://docs.python.org/3.3/library/functions.html#hash .
а значения hash () поступают из метода __hash__ объекта. В документе говорится следующее:
Вот почему у вас есть различное хеш-значение для одной и той же строки в другой консоли.
То, что вы реализуете, - не лучший способ.
Если вы хотите вычислить хеш-значение строки, просто используйте hashlib
hash () нацелен на получение хеш-значения объекта, а не на волнение.
источник
hash()
идеально подходит для строковых или числовых значений. Вы путаете это с__hash__
пользовательский метод, используемый приhash()
обеспечить собственную реализацию хеш - значения.