Есть ли значительные накладные расходы при использовании разных версий хеширования sha (модуль hashlib)

Модуль hashlib Python предоставляет следующие конструкторы хэш-алгоритмов: md5(), sha1(), sha224(), sha256(), sha384() и sha512().

Предполагая, что я не хочу использовать md5, есть ли большая разница в использовании, скажем, sha1 вместо sha512? Я хочу использовать что-то вроде hashlib.shaXXX(hashString).hexdigest(), но поскольку это только для кеширования, я не уверен, что мне нужны (возможные) дополнительные накладные расходы в размере 512 ...

Существуют ли эти накладные расходы, и если да, то насколько они велики?


person Emilien    schedule 10.02.2010    source источник
comment
Если это для кеширования, зачем вам безопасный хеш?   -  person President James K. Polk    schedule 11.02.2010
comment
Что вы обнаружили, когда пробовали разные методы и измеряли их эффективность?   -  person Greg Hewgill    schedule 11.02.2010
comment
Вероятно, @GregHewgill имел в виду, что существует удобный модуль стандартной библиотеки timeit, который делает такие измерения настолько тривиальными, что проще просто рассчитать время, чем спрашивать об этом, особенно когда он запускается из командной строки.   -  person Peter Hansen    schedule 11.02.2010
comment
@GregS что бы вы использовали вместо безопасного хеша? Мне нужен отпечаток Python dict (содержащий параметры поиска), чтобы я мог определить (1), был ли этот поиск уже выполнен раньше и (2, если это новый поиск), доступны ли результаты поиска для отображать.   -  person Emilien    schedule 11.02.2010
comment
Я полагаюсь на Sttwister. Поскольку я кое-что узнал из обмена, я голосую за вопрос.   -  person President James K. Polk    schedule 13.02.2010


Ответы (2)


Почему бы просто не провести сравнительный анализ?

>>> def sha1(s):
...     return hashlib.sha1(s).hexdigest()
...
>>> def sha512(s):
...     return hashlib.sha512(s).hexdigest()
...
>>> t1 = timeit.Timer("sha1('asdf' * 100)", "from __main__ import sha1")
>>> t512 = timeit.Timer("sha512('asdf' * 100)", "from __main__ import sha512")
>>> t1.timeit()
3.2463729381561279
>>> t512.timeit()
6.5079669952392578

Итак, на моей машине hash512 в два раза медленнее, чем sha1. Но, как сказал GregS, зачем вам использовать безопасный хеш для кеширования? Попробуйте встроенные алгоритмы хеширования, которые должны быть очень быстрыми и настраиваемыми:

>>> s = "asdf"
>>> hash(s)
-618826466
>>> s = "xxx"
>>> hash(s)
943435
>>> hash("xxx")
943435

А еще лучше использовать встроенные словари Python. Может быть, вы расскажете нам больше о том, что планируете кэшировать.

РЕДАКТИРОВАТЬ: Я думаю, что вы пытаетесь добиться чего-то вроде этого:

hash = hashlib.sha1(object_to_cache_as_string).hexdigest()
cache[hash] = object_to_cache

Под «использованием встроенных словарей Python» я имел в виду то, что вы можете упростить приведенное выше:

cache[object_to_cache_as_string] = object_to_cache

Таким образом, Python позаботится о хешировании, поэтому вам не придется этого делать!

Что касается вашей конкретной проблемы, вы можете обратиться к хешируемым словарям Python, чтобы сделать хешируемый словарь. Затем все, что вам нужно сделать для кеширования объекта, это:

cache[object_to_cache] = object_to_cache

ИЗМЕНИТЬ - Заметки о Python3

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

Ссылки: - https://docs.python.org/3/reference /datamodel.html#object.<▪hash - https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED

person sttwister    schedule 10.02.2010
comment
Спасибо, что нашли время, чтобы протестировать его. Как многие из вас сказали, мне, вероятно, не нужно использовать безопасное хеширование для кеширования. Обычно мне нужно сохранить отпечаток [содержания] словаря. Поскольку я не могу использовать hashlib или hash() непосредственно в словаре, я строил строку, содержащую элементы этого словаря (мне не нравится этот подход), а затем использовал hashlib на ней ... Но теперь вы меня заинтриговали с использованием встроенных словарей Python, что вы имеете в виду? - person Emilien; 11.02.2010
comment
Прочитав ваши комментарии (все вы), я понял, что мне не нужно использовать какое-либо безопасное хеширование, поэтому я реализовал свой собственный алгоритм хеширования. Поскольку в словаре всегда есть определенные элементы, и у каждого значения есть идея, я создаю строку из этих идей и кэширую ее. Спасибо всем. - person Emilien; 14.02.2010
comment
Всем, кто смотрит на этот ответ, рекомендация использовать hash () вместо hashlib для некриптографического хеширования: имейте в виду, что в Python 3 и некоторых реализациях Python 2 hash() не возвращает согласованные значения в разных экземплярах, и поэтому может быть проблематичным, если вы работаете на распределенной платформе и пытаетесь сгенерировать ключи кеша или что-то в этом роде. Например, каждый дино (например, экземпляр Linux) на Heroku, похоже, возвращает другой результат для hash() в той же строке. Это единственное непротиворечивое внутри самого экземпляра. Сообщается, что GAE ведет себя аналогичным образом. - person B Robster; 08.01.2015

Возможно, наивный тест ... но похоже, что это зависит от того, сколько вы хешируете. 2 блока sha512 быстрее, чем 4 блока sha256?

>>> import timeit
>>> import hashlib
>>> for sha in [ x for x in dir(hashlib) if x.startswith('sha') ]:
...   t = timeit.Timer("hashlib.%s(data).hexdigest()" % sha,"import hashlib; data=open('/dev/urandom','r').read(1024)")
...   print sha + "\t" + repr(t.timeit(1000))
...
sha1    0.0084478855133056641
sha224  0.034898042678833008
sha256  0.034902095794677734
sha384  0.01980900764465332
sha512  0.019846916198730469
person MattH    schedule 10.02.2010
comment
Я получил аналогичные результаты. Я думаю, что фактическое обучение здесь состоит в том, что md5 и sha1 схожи по скорости (я также тестировал md5, используя этот метод), и тогда sha512 быстрее, чем все хэши между ними. Поэтому используйте sha1 для скорости и sha512 для лучшего хеширования. Остальные не имеют смысла с точки зрения производительности. - person Adam Nelson; 16.12.2010
comment
Я получил очень разные результаты, возможно, текущая реализация или машины лучше оптимизированы: sha1: 0.00902104377746582 sha224: 0.007354021072387695 sha256: 0.007508993148803711 sha384: 0.004772186279296875 sha512: 0.004884004592895508 - person user; 02.08.2015