一、布隆过滤器(Bloom Filter)
是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。
(1)基本概念
如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。
(2)优点
相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数。另外, Hash函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。布隆过滤器可以表示全集,其它任何数据结构都不能。
(3)缺点
但是布隆过滤器的缺点和优点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。常见的补救办法是建立一个小的白名单,存储那些可能被误判的元素。但是如果元素数量太少,则使用散列表足矣。
另外,一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位列阵变成整数数组,每插入一个元素相应的计数器加1, 这样删除元素时将计数器减掉就可以了。然而要保证安全的删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。在降低误算率方面,有不少工作,使得出现了很多布隆过滤器的变种。
二、字符串转数字的一些hash函数
算法大概有如下几种:
- BKDRHash
- APHash
- DJBHash
- JSHash
- RSHash
- SDBMHash
- PJWHash
- ELFHash
使用方法如下:
var bling = require("bling-hashes");
var hash = bling.bkdr("Hello world!");
三、布隆过滤器(Bloom Filter)与Hash算法
Hash算法在应用中又称为指纹(fingerprint)或者摘要(digest)算法,是一种将任意长度的明文串映射为较短的数据串(hash值)的算法,目前的Hash算法主要是MD5系列算法与SHA系统算法一个好的Hash算法需要具有四个特性,即正向快速 ,逆向困难,输入敏感 ,冲突避免。
- 正向快速 :给定明文和 Hash 算法,在有限时间和有限资源内能计算得到 Hash 值
- 逆向困难:给定Hash 值,在有限时间内难以逆推出明文
- 输入敏感:原始输入信息发生任何改变,新产生的 Hash 值都应该出现很大不同
- 冲突避免:很难找到两段内容不同的明文,使得它们的 Hash 值一致 。冲突避免也叫做抗碰撞性,分为强抗碰撞性与弱抗碰撞性。如果给定明文前提下,无法找到与之碰撞的其他明文,则算法具有弱抗碰撞性;如果无法找到任意两个Hash 碰撞的明文,则称算法具有强抗碰撞性
由于Hash可以将任意内容映射到一个固定长度的字符串,而且不同内容映射到相同串的概率很低 。因此,这就构成了一个很好的“内容→索引”的生成关系。对于给定的内容与存储数组,可以通过构造合适的Hash函数,使内容计算得出的Hash值不超过数组的大小,从而实现快速的基于内容的查找,用以判断"某个元素是否在一个集合内"的问题。但是将映射的Hash值限制在数组大小的范围内,会造成大量的Hash冲突,从而导致性能的急速下降,所以人们基于Hash算法设计出了布隆过滤器
布隆过滤器采用了多个 Hash 函数来提高空间利用率。 对同一个给定输入来说,多个Hash函数计算出多个地址,分别在数组的这些地址上标记为1,进行查找时,进行同样的计算过程,并查看对应元素,如果都为1,则说明较大概率是存在该输入,如下图所示,根据内容执行Hash1,Hash2,HashK等函数,计算出h1,h2,hk等位置,如果这些位置全部是1,则说明abc@gmail.com有很大概率存在
之所以说有很大概率,是因为不管是单一的Hash算法还是布隆过滤器,其思想是一致的,都是基于内容的编码,但是由于存储限制,都可能存在冲突,即两种方法都可能存在误报的问题,同时都不会存在错报的问题。不过在应用中布隆过滤器的误报率远低于单一Hash算法的误报率。
为了答谢大家关注和支持,这次给大家准备了限时领取福利:阿里面试题、百度面试题、滴滴面试题、华为面试题、京东面试题、美团面试题、腾讯面试题、头条面试题、中兴面试题。
还等什么小编推荐自己的linuxC/C++语言交流群:【1106675687】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!前100名进群领取,额外赠送一份价值199的C/C++、linux资料包含(视频教程、电子书、实战项目及代码),下面部分展示。