1. 程式人生 > >常見的一些 Hash 函式

常見的一些 Hash 函式

Hash的主要原理就是把大範圍對映到小範圍;所以,你輸入的實際值的個數必須和小範圍相當或者比它更小。不然衝突就會很多。

不同的應用對Hash函式有著不同的要求;比如,用於加密的Hash函式主要考慮它和單項函式的差距,而用於查詢的Hash函式主要考慮它對映到小範圍的衝突率。

下面介紹一些常用的用於查詢Hash函式。

加法Hash
public class AdditiveHash {

@Test
public void additionHashDemo() {
    int result = this.additiveHash("mykey", 31);
    System.out.println(result);
}

/**
 * 加法hash, 把輸入元素一個一個的加起來構成最後的結果
 * @param prime 任意的質數。質數可以降低碰撞的概率
 * @return 結果在 [0, prime-1]
 */
private int additiveHash(String key, int prime) {
    int hash;
    int i;
    for (hash = key.length(), i = 0; i < key.length(); i++ ) {
        hash += key.charAt(i);
    }
    return hash % prime;   //除以 一個prime的目的只是為了保證結果的範圍
}
}
位運算Hash
@Test
public void rotatingHashDemo() {
    int hash = this.rotatingHash("key", 31);
    System.out.println(hash);
}

/**
 * 標準的旋轉hash, 通過先移位,在進行各種位運算。 比如某個學校同一系的新生,學號前5位相同,最後2位不同,
 * 將最後2位旋轉放置前兩位,其餘的右移。這樣只要輸入前兩位,就可以快速查出學生的資訊。
 * @param key hash key
 * @param prime 任意的質數。質數可以降低碰撞的概率
 */
private int rotatingHash(String key, int prime) {
    int hash;
    int i;
    for (hash = key.length(), i = 0; i < key.length(); i++) {
        hash = (hash<<4)^(hash>>28)^key.charAt(i);
    }
    return (hash % prime);  //除以 一個prime的目的只是為了保證結果的範圍
}
乘法Hash
    @Test
public void bernsteinHashDemo() {
    int result = this.bernsteinHash("key", 31);
    System.out.println(result);
}

@Test
public void RSHashDemo() {
    int result = this.RSHash("key");
    System.out.println(result);
}


/**
 * jdk5.0 中 string 的 hashCode() 方法使用的就是這種乘法hash. 乘數可以是31, 131, 1313。。。<br/>
 * @param key hash key
 * @param prime 質數
 */
private int bernsteinHash(String key, int prime) {
    int hash = 0;
    int i;
    for (i = 0; i < key.length(); i++) {
        hash = prime * hash + key.charAt(i);
    }
    return hash;
}

/**
 * 乘以一個不斷該不變的數
 * @param key hash key
 * @return hash value
 */
private int RSHash(String key) {
    int b = 37855;
    int a = 63689;
    int hash = 0;
    for (int i = 0; i < key.length(); i++) {
        hash = hash * a + key.charAt(i);
        a = a * b;
    }
    return (hash & 0x7FFFFFFF);
}