布隆过滤器(Bloom Filter)

布隆过滤器(Bloom Filter)是一种基于Hash的高效查找数据结构,它可以快速答复“某个元素是否存在”的问题。布隆过滤器只能用于添加元素与查询元素,不可以用于删除元素。git

在布隆过滤器以前,使用的是基于Hash的快速查找算法。Hash能够将一个元素进行哈希,而后根据哈希值映射到数组的某一个位置。而且根据Hash算法的优劣,不一样元素映射到相同位置的可能性不一样。可是若是基于Hash的快速查找算法的数组大小被限制在必定的范围内,那么发生哈希冲突的几率将会变大。而且数组范围越小,冲突几率将越大。所以布隆过滤器采用了使用多个hash函数进行运算来提升空间利用率。github

Bloom过滤器原理

布隆过滤器是由一个可变长度为N的二进制数组与一组数量可变M的哈希函数构成。其中,哈希函数为肯定性函数,全部哈希函数的输出值都在1~N之间,与二进制数组相对应。所以,每个元素使用布隆过滤器的哈希函数进行运算都将会获得相同的结果。
Bloom Filter算法

插入一个元素

假设咱们须要插入一个元素到布隆过滤器中,咱们须要使用不一样的哈希函数进行运算生成不一样的哈希值,而且根据生成的哈希值将二进制数组对应的Bit位置为1.例如插入字符串"Bloom"到过滤器中,使用三种哈希函数进行计算所获得的哈希值分别为1,3,7,那么布隆过滤器的二进制数组则会变为:
数组

假设咱们插入第二个字符串"Filter"到过滤器中,一样,咱们使用相同的哈希函数进行运算,假设哈希值分别为2,4,7,那么二进制数组则会变为:
数据结构

由于在插入第一个字符串时,哈希值为7的Bit位置已经被置为1,所以不须要更改,只须要将Bit位为2,4置为1便可。ide

查询元素

假设须要查询某个元素是否存在,只须要使用相同的哈希函数进行运算,而后与二进制数组进行Bit值匹配便可。好比,咱们须要查询字符串"hash"是否存在,使用以前的哈希函数进行运算,假设输出的哈希值为4,5,7,因为Bit位为5的位置仍然为0,因此对于字符串"hash"并不存在。
函数

可是若是运算的哈希值为2,3,7,咱们也只能说该字符串有可能存在。由于随着存储的数组越多,将会有越多的Bit位被置为1,即便某个字符串没有存储,可是有可能该字符串的哈希值与其余被存储的数据哈希值重复,仍然可能误判为该字符串存在。
ui

所以,对于查询某个元素,只能断定某个元素必定不存在或者有可能存在,并不能断定某个元素必定存在3d

选择合适的数组长度与哈希函数数量

所以须要设置合适的数组长度与哈希函数数量。code

  • 数组越短则更容易全部的位置被置为1,那么可能查询任何值都会被判断可能存在,过滤的效率将大大下降。
  • 数组越长则会增长过滤效率,可是过长则会耗费大量空间。

哈希函数数量也会影响过滤效率.

  • 哈希函数越多则二进制位置1的次数越多,效率也会变低
  • 可是数量过少的话误判率将会变高。

能够经过如下公式计算合适的数组长度与哈希函数数量:

其中k为哈希函数个数,m 为布隆过滤器长度,n 为插入的元素个数,p 为误报率。

Hash与布隆过滤器

实际上,不管是 Hash,仍是布隆过滤器,基本思想是一致的,

  • 都是基于内容的编址。
  • Hash 函数存在冲突,布隆过滤器也存在冲突。
  • 均可能误报,但绝对不会漏报。

参考文献: https://github.com/yeasy/blockchain_guide/blob/master/05_crypto/bloom_filter.md

相关文章
相关标签/搜索