布隆過濾器(Bloom Filter)是一種基於Hash的高效查找數據結構,它可以快速答覆「某個元素是否存在」的問題。布隆過濾器只能用於添加元素與查詢元素,不可以用於刪除元素。git
在布隆過濾器以前,使用的是基於Hash的快速查找算法。Hash能夠將一個元素進行哈希,而後根據哈希值映射到數組的某一個位置。而且根據Hash算法的優劣,不一樣元素映射到相同位置的可能性不一樣。可是若是基於Hash的快速查找算法的數組大小被限制在必定的範圍內,那麼發生哈希衝突的機率將會變大。而且數組範圍越小,衝突機率將越大。所以布隆過濾器採用了使用多個hash函數進行運算來提升空間利用率。github
布隆過濾器是由一個可變長度爲N的二進制數組與一組數量可變M的哈希函數構成。其中,哈希函數爲肯定性函數,全部哈希函數的輸出值都在1~N之間,與二進制數組相對應。所以,每個元素使用布隆過濾器的哈希函數進行運算都將會獲得相同的結果。
算法
假設咱們須要插入一個元素到布隆過濾器中,咱們須要使用不一樣的哈希函數進行運算生成不一樣的哈希值,而且根據生成的哈希值將二進制數組對應的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
哈希函數數量也會影響過濾效率.
能夠經過如下公式計算合適的數組長度與哈希函數數量:
其中k
爲哈希函數個數,m
爲布隆過濾器長度,n
爲插入的元素個數,p
爲誤報率。
實際上,不管是 Hash,仍是布隆過濾器,基本思想是一致的,
參考文獻: https://github.com/yeasy/blockchain_guide/blob/master/05_crypto/bloom_filter.md