Хеширование (скрытие) строк в Python

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

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

Что было бы лучшим для этой цели? Можно ли это сделать со встроенными классами?

4 ответов


во-первых, позвольте мне сказать, что вы не можете гарантировать уникальные результаты. Если вам нужны уникальные результаты для всех строк во Вселенной, вам лучше сохранить саму строку (или сжатую версию).

подробнее об этом в секунду. Давайте сначала сделаем хэши.

hashlib способом

вы можете использовать любой из основных криптографических хэшей в хэш строки с несколько шагов:

>>> import hashlib
>>> sha = hashlib.sha1("I am a cat")
>>> sha.hexdigest()
'576f38148ae68c924070538b45a8ef0f73ed8710'

у вас есть выбор между SHA1, SHA224, SHA256, Значения sha384, криптография SHA512, MD5 и насколько встроенные модули обеспокоены.

в чем разница между этими хэш-алгоритмами?

хэш-функция работает, принимая данные переменной длины и превращая их в данные фиксированной длины.

фиксированная длина, в случае каждого из алгоритмов SHA, встроенных в hashlib, - количество битов, указанное в имени (за исключением sha1, которое составляет 160 бит). Если ты хочешь большей уверенности, что две струны не закончатся. в том же ведре (то же значение хэша) выберите хэш с большим дайджестом (фиксированная длина).

в отсортированном порядке это размеры дайджеста, с которыми вам нужно работать:

Algorithm  Digest Size (in bits)
md5        128
sha1       160
sha224     224
sha256     256
sha384     384
sha512     512

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

Подождите, а как же hash()?

построен в hash() функция возвращает целые числа, которые также могут быть просты в использовании для цели, которую вы описываете. Там хотя проблем.

>>> hash('moo')
6387157653034356308
  1. если ваша программа будет работать на разных системах, вы не можете быть уверены в том, что hash вернет то же самое. На самом деле, я работаю на 64-битной коробке, используя 64-битный Python. Эти значения будут сильно отличаться от 32-битного Python.

  2. для Python 3.3+, as @gnibbler указано, hash() рандомизируется между прогонами. Он будет работать для одного запуска, но почти наверняка не будет работать через прогоны вашей программы (вытягивая из текстового файла, который вы упомянули).

зачем hash() быть построены таким образом? Ну, встроенный хэш существует по одной конкретной причине. Хэш-таблицы / словари / поиск таблиц в памяти. Не для криптографического использования, а для дешевых поисков во время выполнения.

не используйте hash() используйте hashlib.


вы можете просто использовать модуль base64 для достижения своей цели:

>>> import base64
>>> a = 'helloworld'
>>> encoded_str = base64.encodestring(a)
>>> encoded_str
'aGVsbG93b3JsZA=='
>>> base64.decodestring(encoded_str)
'helloworld'
>>>

конечно, вы также можете использовать модуль hashlib, он более безопасен, потому что хешированная строка не может (или очень сильно) быть декодирована, но для вашего вопроса base64 достаточно - "это действительно не должно быть безопасным"


обратите внимание, что строковый хэш Python не "определен" - он может и меняется в разных выпусках и реализациях. Таким образом, хранение хэша строки Python создаст трудности. Строковый хэш CPython также не пытается быть "неясным".

стандартным подходом является использование хэш-функции предназначен для такого рода вещей. Вот так:

>>> import hashlib
>>> encoded = hashlib.sha1("abcdef") # "abcdef" is the password
>>> encoded.hexdigest()
'1f8ac10f23c5b5bc1167bda84b833e5c057a77d2'

эта длинная строка шестнадцатеричных цифр является "хэшем". SHA-1 является "сильной" хэш-функцией. Вы можете получить известный, Если вы найдете две строки, которые хэшируют одно и то же значение ;-) и учитывая тот же ввод, он вернет тот же "hexdigest" на всех платформах во всех выпусках и реализациях Python.


просто использовать hash() встроенная функция, например:

s = 'a string'
hash(s)
=> -8411828025894108412