卡布隆板过滤器是什么

这是本人学习了很多篇论文之后,总结了很多布隆过滤器的原理
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
布隆过滤器BF
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口收藏,1.2k 浏览
Hash (哈希,或者散列)函数在计算机领域,尤其是数据快速查找领域,加密领域用的极广。
其作用是将一个大的数据集映射到一个小的数据集上面(这些小的数据集叫做哈希值,或者散列值)。
一个应用是Hash table(散列表,也叫哈希表),是根据哈希值 (Key value) 而直接进行访问的数据结构。也就是说,它通过把哈希值映射到表中一个位置来访问记录,以加快查找的速度。下面是一个典型的 hash 函数 / 表示意图:
哈希函数有以下两个特点:
如果两个散列值是不相同的(根据同一函数),那么这两个散列值的原始输入也是不相同的。
散列函数的输入和输出不是唯一对应关系的,如果两个散列值相同,两个输入值很可能是相同的。但也可能不同,这种情况称为 “散列碰撞”(或者 “散列冲突”)。
缺点: 引用吴军博士的《数学之美》中所言,哈希表的空间效率还是不够高。如果用哈希表存储一亿个垃圾邮件地址,每个email地址 对应 8bytes, 而哈希表的存储效率一般只有50%,因此一个email地址需要占用16bytes. 因此一亿个email地址占用1.6GB,如果存储几十亿个email address则需要上百GB的内存。除非是超级计算机,一般的服务器是无法存储的。
所以要引入下面的 Bloom Filter。
布隆过滤器 Bloom Filter
如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间越来越大。同时检索速度也越来越慢。
Bloom Filter 是一种空间效率很高的随机数据结构,Bloom filter 可以看做是对 bit-map 的扩展, 它的原理是:
当一个元素被加入集合时,通过 K 个 Hash 函数将这个元素映射成一个位阵列(Bit array)中的 K 个点,把它们置为 1。检索时,我们只要看看这些点是不是都是 1 就(大约)知道集合中有没有它了:
如果这些点有任何一个 0,则被检索元素一定不在;
如果都是 1,则被检索元素很可能在。
It tells us that the element either definitely is not in the set or may be in the set.
它的优点是空间效率和查询时间都远远超过一般的算法,布隆过滤器存储空间和插入 / 查询时间都是常数O(k)。另外, 散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。
但是布隆过滤器的缺点和优点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。
(误判补救方法是:再建立一个小的白名单,存储那些可能被误判的信息。)
另外,一般情况下不能从布隆过滤器中删除元素. 我们很容易想到把位数组变成整数数组,每插入一个元素相应的计数器加 1, 这样删除元素时将计数器减掉就可以了。然而要保证安全地删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。
可以快速且空间效率高的判断一个元素是否属于一个集合;用来实现数据字典,或者集合求交集。
如: Google chrome 浏览器使用bloom filter识别恶意链接(能够用较少的存储空间表示较大的数据集合,简单的想就是把每一个URL都可以映射成为一个bit)
得多,并且误判率在万分之一以下。
又如: 检测垃圾邮件
假定我们存储一亿个电子邮件地址,我们先建立一个十六亿二进制(比特),即两亿字节的向量,然后将这十六亿个二进制全部设置为零。对于每一个电子邮件地址 X,我们用八个不同的随机数产生器(F1,F2, ...,F8) 产生八个信息指纹(f1, f2, ..., f8)。再用一个随机数产生器 G 把这八个信息指纹映射到 1 到十六亿中的八个自然数 g1, g2, ...,g8。现在我们把这八个位置的二进制全部设置为一。当我们对这一亿个 email 地址都进行这样的处理后。一个针对这些 email 地址的布隆过滤器就建成了。
再如此题:
A,B 两个文件,各存放 50 亿条 URL,每条 URL 占用 64 字节,内存限制是 4G,让你找出 A,B 文件共同的 URL。如果是三个乃至 n 个文件呢?
分析 :如果允许有一定的错误率,可以使用 Bloom filter,4G 内存大概可以表示 340 亿 bit。将其中一个文件中的 url 使用 Bloom filter 映射为这 340 亿 bit,然后挨个读取另外一个文件的 url,检查是否与 Bloom filter,如果是,那么该 url 应该是共同的 url(注意会有一定的错误率)。”
想更一进步的支持我,请扫描下方的二维码,你懂的~
你可能感兴趣的文章
22 收藏,1k 浏览
24 收藏,2.6k 浏览
不要错过 TA 的任何更新
如果这篇文章对你有帮助,记得点赞收藏哦,你的支持是我们的动力 ^___^
本文隶属于专栏
学习笔记 ,分享与反思。
想更一进步的支持我,请扫描文章下方的二维码~
分享到微博?
与我们一起探索更多的未知
专业的开发者技术社区,为用户提供多样化的线上知识交流,丰富的线下活动及给力的工作机会
加入只须一步
举报理由:
推广(招聘、广告、SEO 等)方面的内容
带有人身攻击、辱骂、仇恨等违反条款的内容
与已有问题重复(请编辑该提问指向已有相同问题)
内容质量差,或不适合在本网站出现
答非所问,不符合答题要求
其他原因(请补充说明)
补充说明:
扫扫下载 AppBFcode 布隆过滤器的C语言实现,可以检索海量数据,用于去重 Linux-Unix program 238万源代码下载-
&文件名称: BFcode
& & & & &&]
&&所属分类:
&&开发工具: C-C++
&&文件大小: 2 KB
&&上传时间:
&&下载次数: 16
&&提 供 者:
&详细说明:布隆过滤器的C语言实现,可以检索海量数据,用于去重-Bloom filter C language, you can retrieve huge amounts of data, for the de-emphasis
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&code\bloomfilter.c&&....\bloomfilter.h&&....\hash.c&&....\hash.h&&....\main.c&&code
&近期下载过的用户:
&相关搜索:
&输入关键字,在本站238万海量源码库中尽情搜索:
&[] - 自己编写的将字符串base64加密解密,测试通过,linux可以编译成功,方便移植
&[] - vc++ 与数据库结合,描述怎样利用c++实现数据库操作
&[] - bloom filter 布隆过滤器,这是源码,简单易学易用布隆过滤器是什么_百度知道
布隆过滤器是什么
我有更好的答案
这个问题。。。问度娘吧
其他类似问题
4人觉得有用
为您推荐:
您可能关注的推广回答者:
过滤器的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁布隆过滤器(Bloom Filter) - CSDN博客
什么是布隆过滤器?
维基百科给出的解释如下:
布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制矢量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
如果有1亿个不重复的网址,如何判定某个网址是否包含在这1亿个地址中?可能第一时间就想到用hash表了。但是,如果用hash表,存储1亿个网址,假设1亿个网址都被压缩为8字节的短网址,因为hash表中不可避免总会发生碰撞,如果控制hash表的装填因子在0.5左右,那至少需要的内存大小为:2*8*10^8/(.5G。如果需要存储10亿,100亿的网址呢?有人会说,可以采用位图的方式,将每个网址经过一个哈希函数映射到某一位,比如1亿个网址,只需要1亿位就可以保存,也就只需要1*10^8/()=11.9M。但是因为哈希函数冲突概率太高,假设要将冲突概率降低到1%,至少要将位图长度设定为url个数的100倍,所以使用的内存大小也接近1G了。显然,这种情况下hash表或位图处理就不再合适。这时候就需要用到布隆过滤器了。
布隆过滤器原理
布隆过滤器需要一个位数组,这点和位图类似。还需要k个映射函数,这点和hash表类似。
1)加入元素
首先,将长度为m个位数组的所有的位都初始化为0。如下图:
其中的每一位都是一个二进制位。
对于有n个元素的集合S={s1,s2,...,sn},通过k个映射函数{f1,f2,...,fk},将集合s中的每个元素映射为k个值{b1,b2,..,bk},然后再将位数组中的与之对应的b1,b2,...,bk位设置为1:
这样,就将一个元素映射到k个二进制位了。
2)检查元素是否存在
如果要查找某一个元素是否在集合S中。就可以通过映射函数{f1,f2,...,fk}得到k个值{b1,b2,..,bk},然后判断位数组中对应的b1,b2,...,bk位是否都为1,如果全部为1,则该元素在集合S中,否则,就不在集合S中。
但有没有误判的情况呢?即对应的位数组的位都为1,但元素却不在集合中。答案是有可能会有误判的情况,但这个概率很小,通常在万分之一以下。下文再继续论述。
布隆过滤器误判概率计算
假设布隆过滤器中的hash函数满足假设:每个元素都等概率的hash到m个位中的任何一个,与其他元素被hash到哪个位无关。那么,对某一个特定的位在一个元素被插入时没有被设置为1的概率是:1-1/m。
那么,k个hash函数中没有一个对该位设置为1的概率为:(1-1/m)^k。
如果插入了n个元素,但是都没有对该位设置为1的概率为:(1-1/m)^kn。
所以,插入了n个元素,该位被设置为1的概率为:1-(1-1/m)^kn。
在查询阶段,如果对应某个等待查询元素的k个位全部被设置为1,则判定它在集合中。因此,将元素误判的概率为
根据高等数学中的知识:
可以看出,当m增大或者n减小时,也就是位数组的位数越多或者集合元素数目越少,误判率都会减小。那么,k的值是多少时,可以让误判率最低呢?
经过计算,当k=ln2×m/2时,即k=0.7*m/n时,误判率最低。此时,误判率约等于0.6185^(m/n)。
我们此时可以计算以下,对于n=1亿时,如果取m=10亿位,那么k=7,此时的误判率为0.0082,降到了1%以下,但是只需要119M内存就可以存储。
布隆过滤器误判率表如下:
一个简单的布隆过滤器代码如下:
package com.
import java.util.BitS
public class SimpleBloomFilter {
private BitS
private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37, 61 };
private SimpleHash[] hashFunctions = new SimpleHash[seeds.length];
public SimpleBloomFilter() {
this(2 && 24);
public SimpleBloomFilter(int size) {
bits = new BitSet(size);
for (int i = 0; i & hashFunctions. i++) {
hashFunctions[i] = new SimpleHash(size,seeds[i]);
public void add(String value) {
for (SimpleHash hashFunction : hashFunctions) {
bits.set(hashFunction.getHashCode(value),true);
public boolean contains(String value) {
if (null == value) {
boolean result =
for (SimpleHash hashFunction : hashFunctions) {
result = result && bits.get(hashFunction.getHashCode(value));
public static void main(String[] args) {
SimpleBloomFilter bloomFilter = new SimpleBloomFilter();
String value = &iAm333&;
System.out.println(bloomFilter.contains(value));
bloomFilter.add(value);
System.out.println(bloomFilter.contains(value));
其中,计算hash值的代码:
package com.
public class SimpleHash {
SimpleHash(int size, int seed) {
this.size =
this.seed =
public int getHashCode(String value) {
int result = 0;
int length = value.length();
for (int i = 0; i & i++) {
result = seed * result + value.charAt(i);
return (size - 1) &
}转载请注明出处:

我要回帖

更多关于 卡布隆板 的文章

 

随机推荐