【问题标题】:Is there a significant overhead by using different versions of sha hashing (hashlib module)使用不同版本的 sha 散列(hashlib 模块)是否有很大的开销
【发布时间】:2011-01-15 12:12:54
【问题描述】:

hashlib Python 模块提供以下哈希算法构造函数:md5()sha1()sha224()sha256()sha384()sha512()

假设我不想使用 md5,使用 sha1 而不是 sha512 有很大区别吗?我想使用 hashlib.shaXXX(hashString).hexdigest() 之类的东西,但由于它只是用于缓存,我不确定我是否需要 512 的(最终)额外开销......

这种开销是否存在,如果存在,它有多大?

【问题讨论】:

  • 如果是缓存,为什么需要安全哈希?
  • 当您尝试不同的方法并测量它们的性能时,您发现了什么?
  • @GregHewgill 可能的意思是,有一个方便的标准库模块timeit,它使这样的测量变得如此微不足道,以至于它比询问它更容易计时,尤其是在它运行时从命令行。
  • @GregS 你会用什么来代替安全哈希?我需要一个python dict的指纹(包含搜索参数),以便我可以确定(1)之前是否已经完成了此搜索,以及(2,如果是新搜索)搜索结果是否可用于显示。
  • 我遵从 sttwister。由于我从交流中学到了一些东西,所以我赞成这个问题。

标签: python hash hashlib


【解决方案1】:

为什么不只是对其进行基准测试?

>>> 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 hashable dicts 以使字典可散列。然后,您需要做的就是缓存该对象:

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

【讨论】:

  • 感谢您抽出时间对其进行基准测试。正如你们中的许多人所说,我可能不需要使用安全散列进行缓存。基本上我需要存储字典[内容]的指纹。因为我不能直接在字典上使用hashlibhash(),所以我正在构建一个包含该字典元素的字符串(不喜欢这种方法),然后在它上面使用hashlib...但是现在你对“使用内置 Python 字典”很感兴趣,这是什么意思?
  • 通过阅读你们的 cmets(你们所有人),我意识到我不需要使用任何安全散列,所以我实现了自己的“散列”算法。由于字典总是有特定的元素,并且每个值都有一个想法,我从这些想法创建一个字符串并缓存它。谢谢大家。
  • 对于任何查看此答案的建议使用 hash() 而不是 hashlib 进行非加密散列:请记住,在 Python 3 和 Python 2 的某些实现中,hash() 不会返回一致跨不同实例的值,因此如果您在分布式平台上运行并尝试生成缓存键或类似的东西,可能会出现问题。例如,Heroku 上的每个“dyno”(如 linux 实例)似乎在同一字符串上为 hash() 返回不同的结果。它唯一在实例本身内部是一致的。据报道,GAE 也有类似的行为。
【解决方案2】:

也许是一个幼稚的测试......但它看起来取决于你有多少散列。 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

【讨论】:

  • 我得到了类似的结果。我认为这里事实上的学习是 md5 和 sha1 的速度相似(我也使用这种方法对 md5 进行了基准测试)然后 sha512 比介于两者之间的所有哈希都快。因此,使用 sha1 来提高速度,使用 sha512 来提高哈希值。从性能的角度来看,其他的没有意义。
  • 我得到了非常不同的结果,可能是当前的实现或机器优化得更好:sha10.00902104377746582sha2240.007354021072387695sha2560.007508993148803711sha384:@ 987654329@sha512:0.004884004592895508
猜你喜欢
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
  • 2021-12-11
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2011-03-29
相关资源
最近更新 更多