从LONG哈希列表中查找哈希

时间:2010-11-23 09:23:17

标签: .net hash

我有一个长文本文件,其中包含大约1亿个MD5哈希值。我想散列一小组文件,并找出它们中是否有任何一个哈希值在1亿个哈希列表上。我的1亿个哈希按字母顺序排序。无需将整个列表加载到内存或数据库中,从这个大文本文件中查找哈希值的最有效方法是什么?哈希列表将偶尔更新,但仍将按字母顺序排序。对找到的热门位置不感兴趣。重要的是是否有打击。

3 个答案:

答案 0 :(得分:4)

这种工作中的关键参数是单个磁盘查找的成本。磁盘查找具有固有的延迟,因为必须将读/写磁头移动到正确的位置。在典型的磁盘上,您可以依靠每秒大约一百次查找。另一方面,磁盘在顺序读取方面非常擅长,因此对于每次查找,您可以读取一兆字节的数据,而不需要额外的费用。

我在这里假设“文本文件”具有常规格式。例如,每个哈希值恰好使用33个字节,32个用于MD5结果本身(十六进制),另外一个字节用于“换行符”字符。根据具体格式进行调整。使用这些数字,您的文本文件的长度约为3.3 GB。

由于MD5的作用大多类似于随机函数,因此1亿个哈希值应均匀分布在128位值的空间中。这意味着,给定哈希值,您可以计算该值在文件中的大致位置(如果它在文件中)。例如,哈希值9378ec093d09863d008154f1c8f5ca8f应该在接近 0.5761 * n * 33 的偏移处,其中 n 是大文件中哈希的数量, “33”在上面的段落中解释。 0.5761 0x9378EC 除以 0x1000000 的结果。因此,您可以读取一个兆字节的文本文件,以该计算位置为中心。这将包含大约30000个哈希值。 1亿个随机值的标准偏差大约为10000,因此30000哈希值包含正确的值来判断您的哈希值是否在列表中的可能性很高。如果估计没有,你将不得不读另一兆字节,但这不会经常发生。可能,您可以读取超过一兆字节以使这种情况变得罕见:存在权衡,可以通过实际措施进行调整。

在RAM中有一个(小)哈希值块后,使用二进制搜索。但无论如何,最初的查询成本将完全相形见绌。

备用解决方案使用额外的索引文件。构建一个辅助文件,该文件在大文件中每10000个哈希包含一个。该文件的长度约为330 kB。尽可能将此文件保存在RAM中。使用它(使用二进制搜索)来了解哪个10000哈希序列与您的查找相关。然后从大文件中读取该块。只要哈希列表发生变化,就必须重建索引文件;这有点贵,但不如实际的大文件更改。根据生成大文件的系统,您可能会集成索引文件生成,但成本可以忽略不计。

答案 1 :(得分:2)

我认为文件的二进制搜索最快......你需要先将文件中确切的哈希值作为标题存储,所以你知道搜索的限制。

我已经看到这样做了大文件,例如邮政编码信息,它可以用来治疗。

答案 2 :(得分:0)

如果对它们进行排序,对于小集合中的每个散列,您可以使用二进制搜索查找100 milion散列。

这是我想到的最有效的方式,但如果您不想在内存中存储任何值,则必须随机访问该文件。