十一、哈希算法
業界著名的哈希算法也有很多,比如 MD5、SHA 等。
側重點:在實際應用中,如何用哈希算法解決問題?
一、概述
哈希算法:將任意長度的二進制值串映射為固定長度的二進制值串的映射規則;
哈希值:通過原始數據映射之后得到的二進制值串。
二、哈希算法的設計要求
- (1)從哈希值不能反向推導出原始數據(所以哈希算法也叫單向哈希算法);
- (2)對輸入數據非常敏感,哪怕原始數據只修改了一個 Bit,最后得到的哈希值也大不相同;
- (3)散列沖突的概率要很小,對于不同的原始數據,哈希值相同的概率非常小;
- (4)哈希算法的執行效率要盡量高效,針對較長的文本,也能快速地計算出哈希值。
示例 ==》MD5哈希算法
注:MD5 的哈希值是 128 位的 Bit 長度,為了方便表示,我把它們轉化成了 16 進制編碼
==》無論哈希文本長度,都可得到長度相同的哈希值;
==》兩個相似的文本,得到的哈希值完全不同。
三、應用
最常見的幾種應用:安全加密、唯一標識、數據校驗、散列函數、負載均衡、數據分片、分布式存儲。
1、安全加密
終極目標:一種快速并且很難被破解的哈希算法
(1)安全加密的哈希算法
最常用:MD5(MD5 Message-Digest Algorithm,MD5 消息摘要算法)和SHA(Secure Hash Algorithm,安全散列算法)。
其他:DES(Data Encryption Standard,數據加密標準)、AES(Advanced Encryption Standard,高級加密標準)。
(2)安全加密哈希算法的要求
對用于加密的哈希算法來說,有兩點格外重要:
- 很難根據哈希值反向推導出原始數據==》防止原始數據泄露
- 散列沖突的概率要很小
==》MD5中哈希值是固定的 128 位二進制串,能表示的數據是有限的,最多能表示 2^128 個數據,而非無限的數據。
==》即便哈希算法存在沖突,但是在有限的時間和資源下,哈希算法還是很難破解的。
==》沒有絕對安全的加密
在實際的開發過程中,也需要權衡破解難度和計算時間,來決定究竟使用哪種加密算法。
2、唯一標識(信息摘要)
目標:在海量圖庫中,搜索一張圖是否存在。
思路一:每個圖像取一個唯一標識(信息摘要),eg:圖片的二進制碼串頭取100個字節,中間取100個字節,從最后取100個字節。將這300個字節串聯并通過哈希算法,得到一個哈希字符串,作為圖片的唯一標識。
思路二:提升效率。把每個圖片的唯一標識和相應的圖片文件在圖庫中的路徑信息,都存儲在散列表中。當要查看某個圖片是否在圖庫時,先通過哈希算法對圖片取唯一標識,然后再散列表中查找是否存在該唯一標識。若不存在,則說明不在圖庫中;若存在,可通過散列表中存儲的文件路徑獲取圖片,跟現在要插入的圖片進行全量的比對,看是否完全一樣。若一樣,則說明已存在;若不同,則說明兩張圖片雖唯一標識相同,但不是相同的圖片。
3、數據校驗
目標:如何檢驗文件塊的安全、正確、完整?
思路:
通過哈希算法,對 100 個文件塊分別取哈希值,并且保存在種子文件中。
==》哈希函數對數據敏感
==》當文件塊下載完成之后,通過相同的哈希算法,對下載好的文件塊逐一求哈希值,然后跟種子文件中保存的哈希值比對。如果不同,說明這個文件塊不完整或者被篡改了,需要再重新從其他宿主機器上下載這個文件塊。
4、散列函數
散列函數它對哈希算法的要求非常特別,更加看重的是散列的平均性和哈希算法的執行效率。
5、負載均衡
會話粘滯(session sticky)的負載均衡:在同一個客戶端上,在一次會話中的所有請求都路由到同一個服務器上。
方法:通過哈希算法,對客戶端IP地址或者會話ID計算哈希值,將取得的哈希值與服務器列表的大小進行取模運算,最終得到的值就是應該被路由到的服務器編號。
6、數據分片
(1)統計“搜索關鍵詞”出現的次數
目標:1T的日志文件,記錄用戶的搜索關鍵詞,要統計每個關鍵詞被搜索的次數。
分析:(1) 日志很大,不能放入一臺機器中;(2)一臺機器處理1T數據,耗時長。
方法概述:先對數據分片,然后采取多臺機器處理的方法,來提高處理速度。==》MapReduce 的基本思想
具體方法:用 n 臺機器并行處理。首先從搜索記錄的日志文件中,依次讀取每個搜索的關鍵詞,并通過哈希函數計算哈希值,然后跟n取模,最終得到的值,就是應該被分配到的機器編號。
==》哈希值相同的搜索關鍵詞(也就是說,同一個搜索關鍵詞)被分配到同一個機器上。每個機器分別計算關鍵詞出現的次數,其和就是最終的結果。
(2)快速判斷圖片是否在圖庫中?
目標:1億張圖片,快速判斷圖片是否在圖庫中。
方法概述:同樣進行數據分片==》利用多機處理(n臺機器,每臺機器只維護一部分圖片對應的散列表)。
具體方法:每次從圖庫中讀取一個圖片,計算唯一標識,然后與機器個數n求余取模,得到的值就對應要分配的機器編號,然后將該圖片的唯一標識與路徑發到對應的機器構建散列表。
判斷方法:通過同樣的哈希算法,計算該輸入圖片的唯一標識,然后與機器個數n求余取模。假設得到的值為k,就去編號為k的機器構建的散列表中查找。
設備估算:散列表中每個數據單元包含兩個信息:哈希值和圖片文件路徑。其中,通過MD5計算哈希值(長度為128bit,即16字節);路徑長度上限為256字節,不妨假設其平均長度為128字節。若采用鏈表法來解決沖突,則還需存儲指針,指針占用8字節。
==》估算:散列表中每個數據單元占用152字節
==》設備假設:內存為2G,散列表裝載因子為0.75,則一臺機器可以大約給1000萬(2G*0.75/152)張圖片構建散列表
==》對于1億張圖片來說,大約需要十幾臺機器。
實際:針對這種海量數據的處理問題,采取多機分布式處理==》突破單機內存、CPU等資源限制。
7、分布式存儲——一致性哈希算法
情況:海量數據緩存,利用前面數據分析的思想,即通過哈希算法對數據取哈希值,然后對機器個數取模,得到的值就是應該存儲的緩存機器編號。但是,在機器擴容時,所有的數據都要重新計算哈希值,然后重新搬移到正確的機器上。緩存中數據一下子都失效了,所有的數據請求都會穿透緩存,直接去請求數據庫,很可能會發生 雪崩效應,壓垮數據庫
目標:新加入一臺機器后,并不需要做大量的數據搬移。==》一致性哈希算法
方法:假設有 k 個機器,數據的哈希值范圍為[0, MAX]。將整個范圍劃分為m個小區間(m遠小于k),每個機器負責 m/k 個小區間。當有新機器加入時,將某幾個小區間的數據,從原來的機器中搬移到新的機器中
==》既不用全部計算哈希、搬移數據,也保持各個機器上數據數量的均衡。
總結
- 上一篇: 十、散列表(Hash Table)
- 下一篇: 十二、二叉树