【问题标题】:Is this an appropriate use of python's built-in hash function?这是对python内置哈希函数的适当使用吗?
【发布时间】:2011-10-04 10:31:02
【问题描述】:

我需要比较大块数据的相等性,并且我需要每秒比较很多对,。保证每个对象的长度相同,有可能并且很可能仅在未知位置存在细微差异。

下面的时序表明,如果在数据开头附近有差异,则使用 == 运算符非常快,如果差异位于接近末尾,则速度明显较慢。

>>> import os
>>> s = os.urandom(1600*1200 - 1)
>>> Aimg = b"A" + s
>>> Bimg = b"B" + s
>>> img1 = s + b"1"
>>> img2 = s + b"2"
>>> %timeit Aimg == Bimg
61.8 ns ± 0.484 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
>>> %timeit img1 == img2
159 µs ± 2.83 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

在我的用例中,差异可能位于字节的中间或末尾(上下文:它是未压缩的图像数据)。我寻找一种使用哈希或校验和来加快速度的方法。使用 md5 速度较慢,但​​ Python 的内置 hash 确实加快了速度。

>>> %timeit img1 == img2
160 µs ± 5.96 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit hash(img1) == hash(img2) and img1 == img2
236 ns ± 5.91 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

我对此哈希的技术细节感兴趣,它是否足够像 hash(a) == hash(b) 然后 a == b 时的哈希很有可能?如果哈希冲突相当罕见,则可以接受误报,其目的是在平均情况下加快比较速度。

【问题讨论】:

  • hash 函数依赖于架构

标签: python hash hash-collision


【解决方案1】:

Python 的哈希函数专为提高速度而设计,并映射到 64 位空间。由于birthday paradox,这意味着您可能会在大约 50 亿个条目处发生冲突(可能更早,因为散列函数不是加密的)。此外,hash 的精确定义取决于 Python 实现,并且可能是体系结构甚至机器特定的。不要使用它,您希望在多台机器上获得相同的结果。

md5 被设计为加密哈希函数;即使是输入中的轻微扰动也会完全改变输出。它还映射到 128 位空间,这使得除非您专门寻找碰撞,否则您根本不可能遇到碰撞。

如果您可以处理冲突(即测试存储桶中所有成员之间的相等性,可能使用 MD5 或 SHA2 之类的加密算法),那么 Python 的哈希函数就完美了。

还有一件事:为了节省空间,如果将数据写入磁盘,则应以二进制形式存储数据。 (即struct.pack('!q', hash('abc')) / hashlib.md5('abc').digest())。

附带说明:is 不等同于 Python 中的 ==。你的意思是==

【讨论】:

  • 应该是 !q 而不是 !I 吗?示例struct.pack('!I', hash('abc')) 给了我struct.error: 'I' format requires 0 <= number <= 4294967295
  • @AndyHayden 确实如此。固定。
猜你喜欢
  • 2016-12-10
  • 2023-03-06
  • 2019-08-15
  • 2010-10-12
  • 2011-06-04
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多