Отключить рандомизацию хеша из программы Python
8057 просмотра
2 ответа
Начиная с Python 3.3, алгоритм хеширования недетерминированно солен, чтобы избежать определенного вида атаки. Это хорошо для веб-серверов, но это неприятно при попытке отладки программы: каждый раз, когда я запускаю свой скрипт, содержимое dict повторяется в другом порядке.
В некоторых более ранних версиях python был -R
флаг для включения рандомизации хэшей, но теперь, когда это поведение по умолчанию, этот флаг не был заменен его противоположностью. Рандомизацию можно отключить, установив переменную окружения PYTHONHASHSEED
:
PYTHONHASHSEED
Если эта переменная не установлена или установлена в значение random, случайное значение используется для заполнения хэшей объектов str, bytes и datetime.
Если для PYTHONHASHSEED задано целочисленное значение, оно используется в качестве фиксированного начального числа для генерации хеша () типов, охватываемых рандомизацией хеша.
Уловка в том, что эта переменная должна быть установлена до запуска процесса python. Я пытался установить его с помощью os.putenv()
или внутри os.environ
, но, похоже, они не влияют на метод хеширования. Это не слишком удивительно: я бы не ожидал, что python будет проверять окружение перед каждым поиском набора или словаря! Итак, вопрос остается:
Есть ли способ для программы Python отключить свою собственную рандомизацию хеша?
Автор: alexis Источник Размещён: 13.11.2019 11:35Ответы (2)
16 плюса
Я подозреваю, что это невозможно, к сожалению. Глядя test_hash.py
на HashRandomizationTests
класс и его потомки были добавлены в коммит , который ввел это поведение . Они проверяют поведение хеширования, изменяя среду и запуская новый процесс с PYTHONHASHSEED
явно установленным значением. Возможно, вы могли бы попытаться скопировать этот шаблон.
Я также только что заметил, что вы сказали: « Каждый раз, когда я запускаю свой сценарий, содержание dict повторяется в другом порядке». - Я полагаю, вы знаете collections.OrderedDict
, верно? Это нормальный способ получить надежную итерацию хеша.
Если вы хотите установить значение в своей оболочке, вы можете просто обернуть ваш вызов Python в скрипт bash, например
#! /bin/bash
export PYTHONHASHSEED=0
# call your python program here
Это избавляет от необходимости манипулировать всей вашей средой, пока вы в порядке со скриптом-оберткой.
Или даже просто передать значение в командной строке:
$ PYTHONHASHSEED=0 python YOURSCRIPT.py
Автор: dimo414
Размещён: 02.06.2015 01:48
-1 плюса
Помимо порядка словаря, рандомизация хэшей также может нарушить существующий код, который использует hash()
напрямую. Обходной путь, который решил проблему для меня в этом случае, должен был заменить
hash(mystring)
с участием
int(hashlib.sha512(mystring).hexdigest(), 16)
Для Python 3 потребуется преобразование типа `mystring.encode ('utf-8') для стандартных строк. (Я работал с байтовыми строками.)
Обратите внимание, что диапазон чисел и наличие отрицательных чисел различны. Последний код дает гораздо больший диапазон чисел, и коллизии хэшей крайне маловероятны.
Чтобы воспроизвести тот же 64-битный диапазон hash()
, который можно уменьшить, можно уменьшить количество шестнадцатеричных цифр до 16 (4 бита на цифру) и сдвинуть результат так, чтобы он начинался с наименьшего отрицательного 64-битного числа:
int(hashlib.sha256(mystring).hexdigest()[:16], 16)-2**63
В качестве альтернативы можно взять 8 байтов и использовать int.from_bytes
:
int.from_bytes(hashlib.sha256(mystring).digest()[:8], byteorder='big', signed=True)
Вопросы из категории :
- python Обработка XML в Python
- python Как я могу использовать Python itertools.groupby ()?
- python Python: На какой ОС я работаю?
- python Как я могу создать непосредственно исполняемое кроссплатформенное приложение с графическим интерфейсом на Python?
- python Вызов функции модуля с использованием его имени (строки)
- python Звук Питона («Колокол»)
- python-3.x Могу ли я установить Python 3.x и 2.x на одном компьютере с Windows?
- python-3.x Что является альтернативой execfile в Python 3?
- python-3.x Каков наилучший способ удалить акценты в строке Unicode Python?
- python-3.x Удаление значка TK в окне Tkinter
- python-3.x Преобразовать байты в строку?
- python-3.x Синтаксическая ошибка при печати с Python 3
- hash Есть ли какая-либо функция хэш-кода в JavaScript?
- hash Есть ли фиксированная точка MD5, где md5 (x) == x?
- hash Какой тип данных использовать для поля хешированного пароля и какой длины?
- hash Почему Java hashCode () в String использует 31 в качестве множителя?
- hash Является ли «двойное хеширование» пароля менее безопасным, чем одноразовое хеширование?
- hash Как объединить хэши в Perl?