hash概述git
Hash,通常翻譯作「散列」,也有直接音譯爲「哈希」的,就是把任意長度的輸入(又叫作預映射pre-image)經過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,因此不可能從散列值來肯定惟一的輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。算法
基本概念數據庫
* 若結構中存在和關鍵字K相等的記錄,則一定在f(K)的存儲位置上。由此,不需比較即可直接取得所查記錄。稱這個對應關係f爲
散列函數(Hash function),按這個事先創建的表爲
散列表。
* 對不一樣的關鍵字可能獲得同一散列地址,即key1≠key2,而f(key1)=f(key2),這種現象稱碰撞。具備相同函數值的關鍵字對該散列函數來講稱作
同義詞。綜上所述,根據散列函數H(key)和處理衝突的方法將一組關鍵字映象到一個有限的連續的地址集(區間)上,並以關鍵字在地址集中的「象」 做爲記錄在表中的存儲位置,這種表便稱爲
散列表,這一映象過程稱爲散列造表或
散列,所得的存儲位置稱散列地址。
* 若對於
關鍵字集合中的任一個關鍵字,經
散列函數映象到地址集合中任何一個地址的機率是相等的,則稱此類散列函數爲均勻散列函數(Uniform Hash function),這就是使關鍵字通過散列函數獲得一個「隨機的地址」,從而減小衝突。
性質
全部
散列函數都有以下一個基本特性:若是兩個散列值是不相同的(根據同一函數),那麼這兩個散列值的原始輸入也是不相同的。這個特性是散列函數具備肯定性的結果。但另外一方面,散列函數的輸入和輸出不是一一對應的,若是兩個散列值相同,兩個輸入值極可能是相同的,但不絕對確定兩者必定相等(可能出現哈希碰撞)。輸入一些數據計算出散列值,而後部分改變輸入值,一個具備強混淆特性的散列函數會產生一個徹底不一樣的散列值。
典型的散列函數都有無限定義域,好比任意長度的字節字符串,和有限的值域,好比固定長度的比特串。在某些狀況下,散列函數能夠設計成具備相同大小的定義域和值域間的一一對應。一一對應的散列函數也稱爲排列。可逆性能夠經過使用一系列的對於輸入值的可逆「混合」運算而獲得。
經常使用HASH函數
·直接取餘法:f(x):= x mod maxM ; maxM通常是不太接近 2^t 的一個質數。
·乘法取整法:f(x):=trunc((x/maxX)*maxlongit) mod maxM,主要用於實數。
·平方取中法:f(x):=(x*x div 1000 ) mod 1000000); 平方後取中間的,每位包含信息比較多。
構造方法
散列函數能使對一個數據序列的訪問過程更加迅速有效,經過散列函數,
數據元素將被更快地定位。
(詳細構造方法能夠參考
hash函數中的【哈希表的構造方法】)
1.
直接尋址法:取關鍵字或關鍵字的某個線性函數值爲散列地址。即H(key)=key或H(key) = a·key + b,其中a和b爲常數(這種散列函數叫作自身函數)
2. 數字分析法
3. 平方取中法
4. 摺疊法
5. 隨機數法
6. 除留餘數法:取關鍵字被某個不大於
散列表表長m的數p除後所得的餘數爲散列地址。即 H(key) = key MOD p,p<=m。不只能夠對關鍵字直接取模,也可在摺疊、平方取中等運算以後取模。對p的選擇很重要,通常取素數或m,若p選的很差,容易產生同義詞。
哈希函數
(1)餘數法:先估計整個哈希表中的表項目數目大小。而後用這個估計值做爲除數去除每一個原始值,獲得商和餘數。用餘數做爲哈希值。由於這種方法產生衝突的可能性至關大,所以任何搜索算法都應該可以判斷衝突是否發生並提出取代算法。
(2)摺疊法:這種方法是針對原始值爲數字時使用,將原始值分爲若干部分,而後將各部分疊加,獲得的最後四個數字(或者取其餘位數的數字均可以)來做爲哈希值。
(3)基數轉換法:當原始值是數字時,能夠將原始值的數制基數轉爲一個不一樣的數字。例如,能夠將十進制的原始值轉爲十六進制的哈希值。爲了使哈希值的長度相同,能夠省略高位數字。
(4)數據重排法:這種方法只是簡單的將原始值中的數據打亂排序。好比能夠將第三位到第六位的數字逆序排列,而後利用重排後的數字做爲哈希值。
哈希函數並不通用,好比在數據庫中用可以得到很好效果的哈希函數,用在密碼學或錯誤校驗方面就未必可行。在密碼學領域有幾個著名的哈希函數。這些函數包括MD二、MD4以及MD5,利用散列法將數字簽名轉換成的哈希值稱爲信息摘要(message-digest),另外還有
安全散列算法(SHA),這是一種標準算法,可以生成更大的(60bit)的信息摘要,有點兒相似於MD4算法。