哈希函數在現實生活中應用十分廣泛,例如她已經成為密碼學領域一個熱門話題,很多學者都在研究如何設計、分析和評價Hash函數,以及如何給出一個可證明安全的Hash函數等問題。在一些Bit Torrent下載中,軟件通過計算文件的MD5值檢驗下載到的文件片段的完整性。哈希函數其實是一個壓縮映像,因此不可避免的產生沖突,那么在建造哈希表時不僅要設定一個好的哈希函數,還要設定一種處理沖突的方法。本文簡單討論哈希函數的構造准則和七種構造方法。
哈希函數構造准則
hash函數的構造准則:簡單、均勻。
(1)散列函數的計算簡單,快速;
(2)使哈希地址均勻地分布在地址集{0,1,…,m-1}上,並且沖突最小。
哈希函數常用構造方法
(1)直接定址法
取關鍵字或關鍵字的某個線性函數值為哈希地址:
H(key) = a*key + b
其中a和b為常數,這種哈希函數叫做自身函數。當a=1,b=0時,H(key)=key。
注意:由於直接定址所得地址集合和關鍵字集合的大小相同,因此,對於不同的關鍵字不會發生沖突。但是,因為需要提前確定關鍵字的取值范圍,且取值范圍不能太大,所以,實際中能使用直接定址法的場景少之又少。
舉例:有一個從1歲到100歲的人口統計表,其中,年齡作為關鍵字,哈希函數取關鍵字自身,即哈希函數為H(key)= key。這樣,若要詢問25歲的人有多少,則只要查表中地址為25的桶即可。
(2)相乘取整法
首先用關鍵字key乘上某個常數A(0 < A < 1),並抽取出key*A的小數部分;然后用m乘以該小數后取整。
注意:該方法最大的優點是m的選取比除留余數法要求更低。比如,完全可選擇它是2的整數次冪。雖然該方法對任何A的值都適用,但對某些值效果會更好。Knuth建議選取 0.61803……。
(3)平方取中法
當無法確定關鍵字中哪幾位分布較均勻時,先求出關鍵字的平方值,然后按需要取平方值的中間幾位作為哈希地址。
通過平方擴大差別,另外,中間幾位與關鍵字中的每一位都相關,故不同關鍵字會以較高的概率產生不同的、均勻的哈希地址。這是一種較常用的構造哈希函數的方法。
舉例:將一組關鍵字(0100,0110,1010,1001,0111)
平方后得(0010000,0012100,1020100,1002001,0012321)
若取表長為1000,則可取中間的三位數作為散列地址集:(100,121,201,020,123)。
(4)除留余數法
假設散列表長為m,其散列函數公式定義為:
H(key) = key MOD p (p ≤ m)。
MOD表示求余數。這是一種最簡單,也最常用的構造哈希函數的方法。它不僅可以對關鍵字直接取模,也可在對關鍵字進行折迭、平方取中等運算之后取模。溫馨提示,在使用除留余數法時,對p的選擇很重要,一般情況下可以選p為質數或不包含小於20的質因素的合數。
(5)偽隨機數法
選擇一個偽隨機函數,取關鍵字的隨機函數值為它的哈希地址,即 H(key) = random (key),其中random為偽隨機函數。通常,當關鍵字長度不等時采用此法構造哈希函數較恰當。
(6)數字分析法
假設已經知道哈希表中所有的關鍵字值,而且關鍵字值都是數字,則可以取關鍵字值的若干位數字組成哈希地址,這種方法叫做數字分析法。
舉例:有1000個記錄,關鍵字為10位十進制整數x1x2…x10,如哈希表長度為2000。假設經過分析,各關鍵字中 x3、x5和x7的取值分布近似隨機,則可去哈希函數為:h(key)=h(x1x2…x10)=x3x5x7。例如,h(3778597189)=757,h(9166372560)=632。
(7)分段疊加法
將關鍵字拆分成位數相等的幾部分,其中最后一部分的位數可以不同;然后,將這幾部分相加,舍棄最高進位后的結果就是該關鍵字的哈希地址。分段疊加法又可以分成邊界疊加法和移位疊加法兩種,移位疊加是將分割后的每部分低位對齊相加,邊界疊加是將奇數段正序偶數段逆序然后相加。
關鍵字位數很多,而且關鍵字中每一位上數字分布大致均勻時,可以采用折疊法得到哈希地址。
舉例:根據國際標准圖書編號(ISBN)建立一個哈希表。如一個國際標准圖書編號 0-442-20586-4的哈希地址為:
使用移位疊加 5864 +4220+04 =1 0088,故H(0-442-20586-4)= 0088(將分割后的每一部分的最低位對齊)。
使用邊界疊加法疊加 5864 +0224+04 =6092,故H(0-442-20586-4)= 6092(從一端向另一端沿分割界來回疊加)。
小 結
有許多種不同的哈希函數設計方法,這里主要討論了七種常用的、不同類型關鍵字的希函數設計方法。在應用的時候,要因地制宜,不同的場景采用不同的方法。如:關鍵字是ISBN時可以使用分段疊加法構造哈希函數;是整數類型時可以用除留余數法、直接定址法和數字分析法等構造哈希函數;是小數類型說常用偽隨機數法來構造哈希函數等。
Reference
https://blog.csdn.net/xitie8523/article/details/93972090
https://blog.csdn.net/m0_37925202/java/article/details/82015731
https://www.cnblogs.com/qixinbo/p/7965466.html
https://www.cnblogs.com/gj-Acit/archive/2013/05/06/3062628.html