高效的“滚动/移动哈希”计算(如移动平均值)

时间:2013-01-11 14:25:16

标签: c++ hash

我正在尝试优化一个程序,该程序需要在流的每个位置(字节)处为数据流中的常量窗口计算散列。需要查找比可用RAM大得多的磁盘文件中的重复。目前我为每个窗口计算单独的md5哈希,但是它花费了很多时间(窗口大小是几千字节,所以每个数据字节被处理几千次)。我想知道是否存在一种方法来计算常量(窗口大小无关)时间内的每个后续哈希值(如移动平均值中1个元素的加法和减法)?散列函数可以是任何东西,只要它不给出长哈希(50-100位是可以的)并且其计算相当快。它还必须在多达数万亿个不随机的窗口(TB数据)上几乎不进行任何分类 - 在我的情况下,每次碰撞都意味着磁盘访问(crc32很弱,md5在这方面还可以)。

如果您指的是Linux上现有的库函数(如果有的话),我将非常感激。

这是我的第一个问题,如果我做错了,请宽容。

的问候, 的Bartosz

2 个答案:

答案 0 :(得分:3)

关于rolling hashes的维基百科文章有ngramhashing的链接,它在C ++中实现了一些不同的技术,包括:

  • 随机化Karp-Rabin(有时称为Rabin-Karp)
  • 通过循环多项式(也称为Buzhash)进行哈希
  • 不可约多项式的哈希

(也可在GitHub上找到)

答案 1 :(得分:0)

您所描述的内容非常接近重复数据删除存储中使用的基本方法。

重复数据删除系统,我们通常使用Rabin's fingerprinting方法作为快速滚动哈希函数。 然而,虽然Rabin指纹是良好且易于理解的碰撞属性,但它不具有加密安全性,即成为碰撞。检查例如如何Bentley et al. used such a method in their compression method。问题是你能否忍受多少碰撞。如果你能忍受偶尔的碰撞,那么一个好的Rabin指纹实现可能是一个好主意。好的实现每个核心每秒可以处理超过200 MB的数据。

我不知道任何方法几乎没有碰撞(也就是加密安全)并且同时滚动。作为PlasmaHH,我怀疑这实际上是可能的。

想想你是否可以放宽限制。也许你可以错过一些重复。在这些情况下,可以采用更快的方式。