Bloom过滤器及其多个哈希函数

时间:2018-02-11 00:58:35

标签: algorithm hash bloom-filter murmurhash

我正在实施一个简单的布隆过滤器作为练习。

Bloom过滤器需要多个哈希函数,出于实际目的,我没有。

假设我想拥有3个哈希函数,仅仅获取我正在检查其成员资格的对象的哈希是否足够,哈希(使用murmur3)然后添加+1,+ 2,+ 3(对于3个不同的哈希)再次哈希之前?

由于murmur3函数具有非常好的雪崩效应(实际上是分散结果),这对于所有目的来说都不合理吗?

的伪代码:

function generateHashes(obj) {
  long hash = murmur3_hash(obj);
  long hash1 = murmur3_hash(hash+1);
  long hash2 = murmur3_hash(hash+2);
  long hash3 = murmur3_hash(hash+3);
  (hash1, hash2, hash3)
}

如果没有,对此有什么简单有用的方法?我希望有一个解决方案,如果需要,我可以轻松扩展更多哈希函数。

由于

3 个答案:

答案 0 :(得分:5)

AFAIK,通常的方法是实际上不使用多个哈希函数。而是哈希一次,然后将结果哈希拆分为2、3或Bloom过滤器所需的部分。因此,例如,创建一个128位的哈希并将其分成2个每个64位的哈希。

https://github.com/Claudenw/BloomFilter/wiki/Bloom-Filters----An-overview

答案 1 :(得分:0)

布隆过滤器的哈希函数应足够独立且随机。 murmur hash非常适合此目的。因此,您的方法是正确的,并且可以生成尽可能多的新哈希。出于教育目的,这很好。

但是在现实世界中,多次运行哈希函数非常耗时,因此通常的方法是在不实际计算哈希的情况下创建临时哈希。

要纠正@memo,不要通过将散列拆分成多个部分来完成,因为散列的宽度应保持恒定(并且您不能将64位散列拆分为64个以上的部分;))。方法是获得两个独立的哈希并将其组合。

function generateHashes(obj) {
  // initialization phase
  long h1 = murmur3_hash(obj);
  long h2 = murmur3_hash(h1);

  int k = 3; // number of desired hash functions
  long hash[k];

  // generation phase
  for (int i=0; i<k; i++) {
      hash[i] = h1 + (i*h2);

  return hash;
}

如您所见,这种创建新哈希的方法是一个简单的乘加运算。

答案 2 :(得分:-1)

这不是一个好方法。让我尝试解释一下。布隆过滤器allows you to test if an element most likely belongs to a set, or if it absolutely doesn’t. In others words, false positives may occur, but false negatives won’t.

参考:https://sc5.io/posts/what-are-bloom-filters-and-why-are-they-useful/

让我们考虑一个例子:

您有一个输入字符串'foo',我们将其传递给多个哈希函数。 murmur3哈希给出输出K,此哈希值上的后续哈希给出xyz

现在假设您还有另一个字符串“ bar”,碰巧它的murmur3哈希也是K。其余的哈希值?它们将是xyz,因为在您提出的方法中,后续哈希函数不取决于输入,而是取决于第一个哈希函数的输出。

long hash1 = murmur3_hash(hash+1);
long hash2 = murmur3_hash(hash+2);
long hash3 = murmur3_hash(hash+3);

如链接中所述,其目的是在集合中执行概率搜索。如果我们搜索“ foo”或“ bar”,我们会说这两者都“可能”存在。因此,误报的百分比会增加。

换句话说,此Bloom筛选器的行为类似于简单的哈希函数。因为只有第一个哈希函数才能确定搜索结果,所以它的“绽放”方面不会出现。

希望我能充分解释。如果您还有其他后续查询,请在评论中让我知道。乐于协助。