问题
不安全的网页的黑名单包含100亿个URL,每个URL最多占用64B。现在想要饰演一个网页过滤系统,利用该系统可以快速判断网页的URL是否在黑名单上,请设计该系统。
要求:该系统允许有万分之一的判断失误率。使用额外空间不许超过30G
哈希函数
性质
-
无限的输入值域
-
同样的输入,返回值一样
-
传入不一样的值时,可能会返回一样的值
这是必然的,因为输入域无穷大,还有同一的离散输出域
-
最重要的性质是输入不同的值,返回值均匀的分布在输出域上
布隆过滤器
操作步骤
-
假设有一个长度为
length
的bit
类型的数组,每个bit
都只有 0/1 两种状态,初始状态全部为0 -
再假设一共有 k 个完全独立的哈希函数,每个哈希函数算出的结果都对 length 取余,得到一个 0 ~ length 之间的数字,然后把的bit数组的对应位置改为1(描黑)
-
每个URL都重复上两个步骤,每个对象都可以涂黑一部分白位置,遇到的黑色位置继续保持黑色
最终生成的这个BitMap
就代表了刚刚所有的URL集合。
检查步骤
假设一个对象为 s
- 通过刚刚生成过滤器的时候的所有 K 个哈希函数计算 取余之后的 k 个值
- 看这些位置是否是黑色的
- 如果这些位置全是黑色!!!那么这个URL有很大的可能就是黑名单中的不安全网址【因为有可能哈希碰撞,所有的哈希函数的计算结果全部碰撞之前计算过的某个或者多个URL的位置】
- 如果其中有一个不是黑色的,那么这个 URL 一定不是 黑名单中的不安全网址
工作逻辑
宁可错杀三千,绝不放过一个!
如何确定数据
BitMap
长度
刚刚题目中说:URL为 100亿,失误率不超过万分之一,也就是 0.0001
所以 数组长度由 公式
l
e
n
g
t
h
=
−
n
×
l
n
p
(
l
n
2
)
2
length = -\frac{n \times ln p }{(ln2)^2}
length=−(ln2)2n×lnp
带入
n
=
100
亿
{n = 100亿}
n=100亿, 概率
p
=
0.0001
{p = 0.0001}
p=0.0001,可得结果
19.19
×
n
{19.19 \times n}
19.19×n , 向上取整
20
×
n
{20 \times n}
20×n , 约等于 25 GB。
哈希函数个数
由公式:
k
=
l
n
2
×
m
n
≈
0.7
×
m
n
k = ln2 \times \frac{m}{n} ≈ 0.7 \times \frac{m}{n}
k=ln2×nm≈0.7×nm
所以 哈希函数个数为 14个。
重新计算失误率
把刚刚得到的 数组长度和 哈希函数个数分别带入公式:
(
1
−
e
−
n
×
k
m
)
k
(1 - e^ {- \frac{n \times k}{m}})^k
(1−e−mn×k)k
即可计算真实的失误率。
具体三个函数推导过程略。