我正在实施一个简单的布隆过滤器作为练习。
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)
}
如果没有,对此有什么简单有用的方法?我希望有一个解决方案,如果需要,我可以轻松扩展更多哈希函数。
由于
答案 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
,此哈希值上的后续哈希给出x
,y
和z
现在假设您还有另一个字符串“ bar”,碰巧它的murmur3
哈希也是K
。其余的哈希值?它们将是x
,y
和z
,因为在您提出的方法中,后续哈希函数不取决于输入,而是取决于第一个哈希函数的输出。
long hash1 = murmur3_hash(hash+1);
long hash2 = murmur3_hash(hash+2);
long hash3 = murmur3_hash(hash+3);
如链接中所述,其目的是在集合中执行概率搜索。如果我们搜索“ foo”或“ bar”,我们会说这两者都“可能”存在。因此,误报的百分比会增加。
换句话说,此Bloom筛选器的行为类似于简单的哈希函数。因为只有第一个哈希函数才能确定搜索结果,所以它的“绽放”方面不会出现。
希望我能充分解释。如果您还有其他后续查询,请在评论中让我知道。乐于协助。