2015-07-01 5 views
1

Является ли python's hash функцией портативной?Является ли python hash() переносимым?

Под «переносной» я имею в виду, будут ли они возвращать те же результаты (для тех же данных) в версиях, платформах и реализациях python?

Если нет, существует ли какая-либо альтернатива ему, которая предоставляет такие функции (в то же время способные объединять общие структуры данных)?


The documentation не особо полезно. This question ссылается на библиотеку, которая, похоже, сворачивает свою собственную версию, но я не уверен, что причиной этого станет не-переносимость.

+0

'hash' предназначен для использования только с типом' dict', который реализуется как хэш-таблица. Вероятно, вам нужна функция из модуля hashlib в стандартной библиотеке. – chepner

+0

@chepner Я ищу что-то, что хеширует произвольные структуры данных, такие как 'hash', я не думаю, что' hashlib' делает это? – goncalopp

+0

'hash' не может создавать произвольные структуры данных hash. (Попробуйте передать 'dict' или' set' 'hash'.) – chepner

ответ

2

Нет, hash() не гарантированно переносится.

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

От object.__hash__() documenation:

По умолчанию __hash__() значения, ул байтов и объекты даты и времени являются «соленый» с непредсказуемым случайным значением. Хотя они остаются постоянными в рамках отдельного процесса Python, они не предсказуемы между повторными вызовами Python.

Это предназначено для обеспечения защиты от отказа в обслуживании, вызванного тщательно подобранными входами, которые используют наихудшую производительность вложения вложения, сложность O (n^2). См. http://www.ocert.org/advisories/ocert-2011-003.html.

Изменение значений хэша влияет на порядок итераций диктов, множеств и других отображений. Python никогда не предоставлял гарантии об этом заказе (и обычно он варьируется между 32-битными и 64-битными сборками).

См. Также PYTHONHASHSEED.

Python 2.6.8 и 3.2.3 и новее поддерживают ту же функцию, но обычно отключены.

В Python 3.2 представлен sys.hash_info named tuple, который дает вам подробную информацию о реализации хеша для текущего интерпретатора.

Если вам нужен переносимый хеш, существует множество реализаций. Стандартная библиотека включает в себя криптографическую хэш-библиотеку под названием hashlib; эти реализации, безусловно, переносимы. Другим вариантом будет mm3 package, который обеспечивает Murmur3 non-cryptographic hash function implementations.

Общие структуры данных необходимо сначала преобразовать в байты; вы можете использовать для этого сериализацию, такую ​​как модули json или pickle.

+0

Это отличный ответ на главный вопрос. Что касается альтернативы, я [выкопал немного больше] (http://stackoverflow.com/questions/5417949/computing-an-md5-hash-of-a-data-structure), и это похоже на сериализацию json - разумная альтернатива. Если вы не возражаете, чтобы я редактировал ваш ответ, я мог бы включить эту информацию. – goncalopp

+0

@goncalopp: сериализация в JSON не даст вам компактный хеш; вам все равно придется запускать это через какой-то алгоритм хэширования. Я добавил указатель на 'hashlib'. –

+0

Да, вы можете запустить его через hashlib, как в [этом ответе] (http://stackoverflow.com/a/10288255/1595865). Примечание. Я отредактировал вопрос, чтобы уточнить. Я ищу что-то, что хеширует данные-структуры как 'hash', а не только строки – goncalopp

Смежные вопросы