什麼是雜湊演算法
將任意長度的二進位制值串對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,得到的二進位制值串就是雜湊值。
一個hash演算法需要滿足幾點要求:
- 從雜湊值不能反向推匯出原始資料(所以雜湊演算法也叫單向雜湊演算法);
- 對輸入資料非常敏感,哪怕原始資料只修改了一個bit,最後得到的hash值也大不相同;
- 雜湊衝突的概率很小,不同的原始資料,雜湊值相同的概率非常小;
- 雜湊演算法的執行效率要儘量高效,針對較長的文字,也能快速的計算出雜湊值。
雜湊演算法的應用
- 安全加密
- MD5(訊息摘要演算法)、SHA(安全雜湊)、DES(資料加密標準)、AES(高階加密標準)等。
- 雜湊演算法無法做到零衝突(鴿巢原理):雜湊值是固定長度的資料串(如MD5:128bit)因此雜湊值的數量也是有限的2^128。對於無限的資料進行雜湊演算法得到有限的雜湊值,肯定會有衝突的。但如2^128已經是個很龐大的資料範圍了,想破解非常之難了。
- 實際開發中選取加密演算法,要衡量破解難度和計算時間。
- 唯一標識
通過一個較短的二進位制串表示一個很大的資料。
如果想從海量相簿中查詢一張圖片。因為圖片後設資料(名稱、地點等資訊)可能會相同沒辦法唯一標識一張圖片。因此我們可以從圖片的二進位制碼串(任何檔案在計算中都可以表示成二進位制碼串)前中後三個部位取100B資料,把這300Byte合併通過雜湊演算法(如MD5)得到一個雜湊值作為圖片的唯一標識。在根據前邊學的查詢相關的演算法,可以把圖片的唯一標識作為key,和相應圖片檔案在相簿中的路徑資訊都儲存在雜湊表中,在雜湊表中通過key可以在O(1)下查詢到圖片。
-
資料校驗
資料在網路中進行傳輸,很有可能被惡意修改,導致檔案無法開啟,甚至導致電腦中毒。如何檢測資料是否被篡改呢?雜湊演算法對資料很敏感,只要資料有一點變化生成的雜湊值就會變化,因此可以對資料進行雜湊,得到雜湊值。當收到檔案時,再對檔案進行相同雜湊函式計算得到雜湊值和原始雜湊值進行比較,不同則說明資料被篡改了。 -
雜湊函式
之前的雜湊函式也是雜湊演算法的一種應用,只不過它更關注雜湊後的值是否平均分佈,雜湊函式執行的快慢,因此雜湊函式一般比較簡單,追求效率。
對使用者密碼進行傳輸如何做更安全呢?
僅對密碼進行MD5/SHA加密還是有很大的可能被攻破,因為有的使用者設定的密碼太簡單(如:654321等)攻擊者可以進行字典攻擊:字典中儲存攻擊者可能猜到的各種密碼組合和對應加密後的資料串,這樣拿到加密後的資料,在字典中查詢,很可能就破解了。
針對字典攻擊,可以引入一個鹽,和使用者密碼組合在一起增加密碼複雜度,在進行雜湊演算法加密,這樣就提高了破解難度。
雜湊演算法解決分散式問題
- 負載均衡
如何把同一個客戶端上的所有請求都路由到同一個後端伺服器上呢?
- 最簡單的方法:維護一張客戶端IP和伺服器編號的對映關係表。客戶端每次發請求,找到表中對應的伺服器編號,請求。但是這種方式有幾個弊端:
- 客戶端很多,表會很大,浪費記憶體空間;
- 客戶端上線下線、伺服器擴容縮容都會導致對映關係失效,表的維護成本高。
- 雜湊演算法:對客戶端的IP地址計算雜湊值,再將雜湊值與伺服器編號列表的大小進行取模,得到的值加上伺服器編號起始值就得到了伺服器編號。這樣就保證了同一個IP最終計算得到的編號值都是一樣的(並不需要保證伺服器一直都是同一個)。
- 資料分片
如果有1T的日誌檔案,記錄了使用者的搜尋關鍵字,如何快速統計出每個關鍵詞被搜尋的次數呢?
最開始想到了桶排序,把相同的資料放同一個桶中,最後統計桶中資料個數。但這樣就有兩個問題:
- 有1T的資料,一起取出來計算機記憶體根本放不下,而且還要為桶開闢空間。
- 如何把一個資料放到一個桶中呢?通過哪種對映關係呢?
結合上述問題的到的處理方法:一個計算機放不下,可以用多臺計算機併發處理。這樣我們可以把每臺計算機看做一個桶。那麼如何把資料放到對應的計算機中呢?想到了雜湊演算法:對每個資料計算雜湊值,然後再根計算機編號列表大小n取模的計算機編號,資料就放到對應編號的計算機中。這樣相同資料肯定放在同一個計算機中。在每個計算機在分別計算相同資料出現的次數,最後在合併結果即可。
這種思想(MapReduce)結合了桶(資料分片)、雜湊演算法、雜湊函式(取模對應列表index)。
如果再1億張圖片中找一張圖片,也可以用上述的思想來解決。
針對這種海量資料問題的處理,都可以採用多機分散式處理,藉助這種分片思路可以突破單機記憶體、CPU等資源的限制。
- 分散式儲存
資料分片時如果增加了一臺計算機,那麼原本雜湊函式得到的結果就都失效了,需要全部資料重新計算一次。需要一致性雜湊演算法。(待補充)