使用不同版本的SHA哈希(hashlib模块)是否存在显著开销?

18 投票
2 回答
16777 浏览
提问于 2025-04-15 19:07

hashlib 是一个 Python 模块,它提供了一些常用的哈希算法,比如 md5()sha1()sha224()sha256()sha384()sha512()

假设我不想用 md5,那使用 sha1sha512 之间有什么大区别呢?我想用类似 hashlib.shaXXX(hashString).hexdigest() 的方式来处理,但因为只是为了缓存,我不确定是否需要使用更复杂的 512。

这种复杂性真的存在吗?如果存在,那它有多大呢?

2 个回答

6

这可能是个简单的测试……但看起来结果取决于你要处理的数据量。用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
23

为什么不直接进行基准测试呢?

>>> 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

撰写回答