轉載:http://blog.csdn.net/tanggao1314/article/details/51457585
構造hash函數的方法
- 直接定址法:
直接定址法是以數據元素關鍵字k本身或它的線性函數作為它的哈希地址,即:H(k)=k 或 H(k)=a×k+b ; (其中a,b為常數)。
- 數字分析法:
假設關鍵字集合中的每個關鍵字都是由 s 位數字組成 (u1, u2, …, us),分析關鍵字集中的全體,并從中提取分布均勻的若干位或它們的組合作為地址。
數字分析法是取數據元素關鍵字中某些取值較均勻的數字位作為哈希地址的方法。即當關鍵字的位數很多時,可以通過對關鍵字的各位進行分析,丟掉分布不均勻的位,作為哈希值。它只適合于所有關鍵字值已知的情況。
- 折疊法:
將關鍵字分割成若干部分,然后取它們的疊加和為哈希地址。兩種疊加處理的方法:移位疊加:將分 割后的幾部分低位對齊相加;邊界疊加:從一端沿分割界來回折疊,然后對齊相加。
- 平方取中法:
這是一種常用的哈希函數構造方法。這個方法是先取關鍵字的平方,然后根據可使用空間的大小,選取平方數是中間幾位為哈希地址。
哈希函數 H(key)=“key2的中間幾位”因為這種方法的原理是通過取平方擴大差別,平方值的中間幾位和這個數的每一位都相關,則對不同的關鍵字得到的哈希函數值不易產生沖突,由此產生的哈希地址也較為均勻。
- 減去法:
減去法是數據的鍵值減去一個特定的數值以求得數據存儲的位置。
- 基數轉換法:
將十進制數X看作其他進制,比如十三進制,再按照十三進制數轉換成十進制數,提取其中若干位作為X的哈希值。一般取大于原來基數的數作為轉換的基數,并且兩個基數應該是互素的。
- 除留余數法:
除留余數法的模p取不大于表長且最接近表長m素數時效果最好,且p最好取1.1n~1.7n之間的一個素數(n為存在的數據元素個數)。
- 隨機數法:
設定哈希函數為:H(key) = Random(key)其中,Random 為偽隨機函數
此法適于:對長度不等的關鍵字構造哈希函數。
9.隨機乘數法:
亦稱為“乘余取整法”。隨機乘數法使用一個隨機實數f,0≤f<1,乘積fk的分數部分在0~1之間,用這個分數部分的值與n(哈希表的長度)相乘,乘積的整數部分就是對應的哈希值,顯然這個哈希值落在0~n-1之間。其表達公式為:Hash(k)=「n(fk%1)」其中“fk%1”表示fk 的小數部分,即fk%1=fk-「fk」
10.字符串數值哈希法:
在很都情況下關鍵字是字符串,因此這樣對字符串設計Hash函數是一個需要討論的問題。下列函數是取字符串前10個字符來設計的哈希函數。
- 旋轉法:
旋轉法是將數據的鍵所代表的的數字中的部分位進行旋轉。旋轉法通常并不直接使用在哈希函數上,而是搭配其他哈希函數使用。
例如,某學校同一個系的新生(小于100人)的學號前5位數是相同的,只有最后2位數不同,我們將最后一位數,旋轉放置到第一位,其余的往右移。
解決“ 沖突 ”的方法
常用的解決沖突方法有以下四種:
1.開放定址法
這種方法也稱再散列法,其基本思想是:當關鍵字key的哈希地址p=H(key)出現沖突時,以p為基礎,產生另一個哈希地址p1,如果p1仍然沖突,再以p為基礎,產生另一個哈希地址p2,…,直到找出一個不沖突的哈希地址pi ,將相應元素存入其中。
主要有以下三種:
(1)線性探測再散列
沖突發生時,順序查看表中下一單元,直到找出一個空單元或查遍全表。
(2)二次探測再散列
沖突發生時,在表的左右進行跳躍式探測,比較靈活。
(3)偽隨機探測再散列
具體實現時,應建立一個偽隨機數發生器,(如i=(i+p) % m),并給定一個隨機數做起點。
2.再哈希法
這種方法是同時構造多個不同的哈希函數:
Hi=RH1(key) i=1,2,…,k
當哈希地址Hi=RH1(key)發生沖突時,再計算Hi=RH2(key)……,直到沖突不再產生。這種方法不易產生聚集,但增加了計算時間。
3.拉鏈法
這種方法的基本思想是將所有哈希地址為i的元素構成一個稱為同義詞鏈的單鏈表,并將單鏈表的頭指針存在哈希表的第i個單元中,因而查找、插入和刪除主要在同義詞鏈中進行。鏈地址法適用于經常進行插入和刪除的情況。
4.建立公共溢出區
這種方法的基本思想是:將哈希表分為基本表和溢出表兩部分,凡是和基本表發生沖突的元素,一律填入溢出表
常見hash算法
了解了hash基本定義,就不能不提到一些著名的hash算法,MD5 和 SHA-1 可以說是目前應用最廣泛的Hash算法,而它們都是以 MD4 為基礎設計的。那么他們都是什么意思呢?
這里簡單說一下:
(1)MD4
MD4(RFC 1320)是 MIT 的 Ronald L. Rivest 在 1990 年設計的,MD 是 Message Digest 的縮寫。它適用在32位字長的處理器上用高速軟件實現 —— 它是基于 32 位操作數的位操作來實現的。
(2)MD5
MD5(RFC 1321)是 Rivest 于1991年對MD4的改進版本。它對輸入仍以512位分組,其輸出是4個32位字的級聯,與 MD4 相同。MD5比MD4來得復雜,并且速度較之要慢一點,但更安全,在抗分析和抗差分方面表現更好
(3)SHA-1 及其他
SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小于264的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基于和MD4相同原理,并且模仿了該算法。
那么這些Hash算法到底有什么用呢?
Hash算法在信息安全方面的應用主要體現在以下的3個方面:
- 文件校驗
我們比較熟悉的校驗算法有奇偶校驗和CRC校驗,這2種校驗并沒有抗數據篡改的能力,它們一定程度上能檢測并糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。
MD5 Hash算法的"數字指紋"特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)算法,不少Unix系統有提供計算md5 checksum的命令。
- 數字簽名
Hash 算法也是現代密碼體系中的一個重要組成部分。由于非對稱算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。 對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。
- 鑒權協議
如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。