各種字串Hash函數比較及各種Hash演算法代碼大全__div

來源:互聯網
上載者:User

       常用的字串Hash函數還有ELFHash,APHash等等,都是十分簡單有效方法。這些函數使用位元運算使得每一個字元都對最後的函數值產生影響。另外還有以MD5和SHA1為代表的雜湊函數,這些函數幾乎不可能找到碰撞。

       常用字串雜湊函數有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。對於以上幾種雜湊函數,我對其進行了一個小小的評測。

Hash函數 資料1 資料2 資料3 資料4 資料1得分 資料2得分 資料3得分 資料4得分 平均分
BKDRHash 2 0 4774 481 96.55 100 90.95 82.05 92.64
APHash 2 3 4754 493 96.55 88.46 100 51.28 86.28
DJBHash 2 2 4975 474 96.55 92.31 0 100 83.43
JSHash 1 4 4761 506 100 84.62 96.83 17.95 81.94
RSHash 1 0 4861 505 100 100 51.58 20.51 75.96
SDBMHash 3 2 4849 504 93.1 92.31 57.01 23.08 72.41
PJWHash 30 26 4878 513 0 0 43.89 0 21.95
ELFHash 30 26 4878 513 0 0 43.89 0 21.95

       其中資料1為100000個字母和數字組成的隨機串雜湊衝突個數。資料2為100000個有意義的英文句子雜湊衝突個數。資料3為資料1的雜湊值與1000003(大素數)求模後儲存到線性表中衝突的個數。資料4為資料1的雜湊值與10000019(更大素數)求模後儲存到線性表中衝突的個數。

        經過比較,得出以上平均得分。平均數為平方平均數。可以發現,BKDRHash無論是在實際效果還是編碼實現中,效果都是最突出的。APHash也是較為優秀的演算法。DJBHash,JSHash,RSHash與SDBMHash各有千秋。PJWHash與ELFHash效果最差,但得分相似,其演算法本質是相似的。

附1:各種雜湊函數的C程式碼

#define M  249997 #define M1 1000001 #define M2 0xF0000000 // RS Hash Function  unsigned int RSHash(char*str) {     unsigned int b=378551 ;     unsigned int a=63689 ;     unsigned int hash=0 ;         while(*str)     {         hash=hash*a+(*str++);         a*=b ;     }         return(hash % M); }  // JS Hash Function  unsigned int JSHash(char*str) {     unsigned int hash=1315423911 ;        while(*str)     {         hash^=((hash<<5)+(*str++)+(hash>>2));     }          return(hash % M); }  // P. J. Weinberger Hash Function  unsigned int PJWHash(char*str) {     unsigned int BitsInUnignedInt=(unsigned int)(sizeof(unsigned int)*8);     unsigned int ThreeQuarters=(unsigned int)((BitsInUnignedInt*3)/4);     unsigned int OneEighth=(unsigned int)(BitsInUnignedInt/8);     unsigned int HighBits=(unsigned int)(0xFFFFFFFF)<<(BitsInUnignedInt-OneEighth);     unsigned int hash=0 ;     unsigned int test=0 ;         while(*str)     {         hash=(hash<<OneEighth)+(*str++);         if((test=hash&HighBits)!=0)         {             hash=((hash^(test>>ThreeQuarters))&(~HighBits));         }     }          return(hash % M); }  // ELF Hash Function  unsigned int ELFHash(char*str) {     unsigned int hash=0 ;     unsigned int x=0 ;        while(*str)     {         hash=(hash<<4)+(*str++);         if((x=hash&0xF0000000L)!=0)         {             hash^=(x>>24);             hash&=~x ;         }     }         return(hash % M); }  // BKDR Hash Function  unsigned int BKDRHash(char*str) {     unsigned int seed=131 ;// 31 131 1313 13131 131313 etc..      unsigned int hash=0 ;         while(*str)     {         hash=hash*seed+(*str++);     }         return(hash % M); }  // SDBM Hash Function  unsigned int SDBMHash(char*str) {     unsigned int hash=0 ;         while(*str)     {         hash=(*str++)+(hash<<6)+(hash<<16)-hash ;     }         return(hash % M); }  // DJB Hash Function  unsigned int DJBHash(char*str) {     unsigned int hash=5381 ;        while(*str)     {         hash+=(hash<<5)+(*str++);     }          return(hash % M); }  // AP Hash Function  unsigned int APHash(char*str) {     unsigned int hash=0 ;     int i ;          for(i=0;*str;i++)     {         if((i&1)==0)         {             hash^=((hash<<7)^(*str++)^(hash>>3));         }         else          {             hash^=(~((hash<<11)^(*str++)^(hash>>5)));         }     }          return(hash % M); } 

附2:Hash演算法大全

/**   * Hash演算法大全<br>   * 推薦使用FNV1演算法   * @algorithm None   * @author Goodzzp 2006-11-20   * @lastEdit Goodzzp 2006-11-20    * @editDetail Create   */public class HashAlgorithms{    /**       * 加法hash       * @param key 字串       * @param prime 一個質數       * @return hash結果       */    public static int additiveHash(String key, int prime)    {        int hash, i;        for (hash = key.length(), i = 0; i < key.length(); i++)            hash += key.charAt(i);        return (hash % prime);    }    /**       * 旋轉hash       * @param key 輸入字串       * @param prime 質數       * @return hash值       */    public static int rotatingHash(String key, int prime)    {        int hash, i;        for (hash = key.length(), i = 0; i < key.length(); ++i)            hash = (hash << 4) ^ (hash >> 28) ^ key.charAt(i);        return (hash % prime);        //   return (hash ^ (hash>>10) ^ (hash>>20));        }    // 替代:        // 使用:hash = (hash ^ (hash>>10) ^ (hash>>20)) & mask;        // 替代:hash %= prime;        /**       * MASK值,隨便找一個值,最好是質數       */    static int M_MASK = 0x8765fed1;    /**       * 一次一個hash       * @param key 輸入字串       * @return 輸出hash值       */    public static int oneByOneHash(String key)    {        int hash, i;        for (hash = 0, i = 0; i < key.length(); ++i)        {            hash += key.charAt(i);            hash += (hash << 10);            hash ^= (hash >> 6);        }        hash += (hash << 3);        hash ^= (hash >> 11);        hash += (hash << 15);        //   return (hash & M_MASK);            return hash;    }    /**       * Bernstein's hash       * @param key 輸入位元組數組       * @param level 初始hash常量       * @return 結果hash       */    public static int bernstein(String key)    {        int hash = 0;        int i;        for (i = 0; i < key.length(); ++i) hash = 33 * hash + key.charAt(i);        return hash;    }    //        //// Pearson's Hash        // char pearson(char[]key, ub4 len, char tab[256])        // {        //   char hash;        //   ub4 i;        //   for (hash=len, i=0; i<len; ++i)         //     hash=tab[hash^key[i]];        //   return (hash);        // }        //// CRC Hashing,計算crc,具體代碼見其他        // ub4 crc(char *key, ub4 len, ub4 mask, ub4 tab[256])        // {        //   ub4 hash, i;        //   for (hash=len, i=0; i<len; ++i)        //     hash = (hash >> 8) ^ tab[(hash & 0xff) ^ key[i]];        //   return (hash & mask);        // }        /**       * Universal Hashing       */    public static int universal(char[] key, int mask, int[] tab)    {        int hash = key.length, i, len = key.length;        for (i = 0; i < (len << 3); i += 8)        {            char k = key[i >> 3];            if ((k & 0x01) == 0) hash ^= tab[i + 0];            if ((k & 0x02) == 0) hash ^= tab[i + 1];            if ((k & 0x04) == 0) hash ^= tab[i + 2];            if ((k & 0x08) == 0) hash ^= tab[i + 3];            if ((k & 0x10) == 0) hash ^= tab[i + 4];            if ((k & 0x20) == 0) hash ^= tab[i + 5];            if ((k & 0x40) == 0) hash ^= tab[i + 6];            if ((k & 0x80) == 0) hash ^= tab[i + 7];        }        return (hash & mask);    }    /**       * Zobrist Hashing       */    public static int zobrist(char[] key, int mask, int[][] tab)    {        int hash, i;        for (hash = key.length, i = 0; i < key.length; ++i)            hash ^= tab[i][key[i]];        return (hash & mask);    }    // LOOKUP3         // 見Bob Jenkins(3).c檔案        // 32位FNV演算法        static int M_SHIFT = 0;    /**       * 32位的FNV演算法       * @param data 數組       * @return int值       */    public static int FNVHash(byte[] data)        {            int hash = (int)2166136261L;            for(byte b : data)                hash = (hash * 16777619) ^ b;            if (M_SHIFT == 0)                return hash;            return (hash ^ (hash >> M_SHIFT)) & M_MASK;        }    /**        * 改進的32位FNV演算法1        * @param data 數組        * @return int值        */    public static int FNVHash1(byte[] data)        {            final int p = 16777619;            int hash = (int)2166136261L;            for(byte b:data)                hash = (hash ^ b) * p;            hash += hash << 13;            hash ^= hash >> 7;            hash += hash << 3;            hash ^= hash >> 17;            hash += hash << 5;            return hash;        }    /**        * 改進的32位FNV演算法1        * @param data 字串        * @return int值        */    public static int FNVHash1(String data)        {            final int p = 16777619;            int hash = (int)2166136261L;            for(int i=0;i<data.length();i++)                hash = (hash ^ data.charAt(i)) * p;            hash += hash << 13;            hash ^= hash >> 7;            hash += hash << 3;            hash ^= hash >> 17;            hash += hash << 5;            return hash;        }    /**        * Thomas Wang的演算法,整數hash        */    public static int intHash(int key)        {         key += ~(key << 15);            key ^= (key >>> 10);            key += (key << 3);            key ^= (key >>> 6);            key += ~(key << 11);            key ^= (key >>> 16);            return key;        }    /**        * RS演算法hash        * @param str 字串        */    public static int RSHash(String str)    {        int b = 378551;        int a = 63689;        int hash = 0;        for (int i = 0; i < str.length(); i++)        {            hash = hash * a + str.charAt(i);            a = a * b;        }        return (hash & 0x7FFFFFFF);    }    /* End Of RS Hash Function */    /**        * JS演算法        */    public static int JSHash(String str)    {        int hash = 1315423911;        for (int i = 0; i < str.length(); i++)        {            hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));        }        return (hash & 0x7FFFFFFF);    }    /* End Of JS Hash Function */    /**        * PJW演算法        */    public static int PJWHash(String str)    {        int BitsInUnsignedInt = 32;        int ThreeQuarters = (BitsInUnsignedInt * 3) / 4;        int OneEighth = BitsInUnsignedInt / 8;        int HighBits = 0xFFFFFFFF << (BitsInUnsignedInt - OneEighth);        int hash = 0;        int test = 0;        for (int i = 0; i < str.length(); i++)        {            hash = (hash << OneEighth) + str.charAt(i);            if ((test = hash & HighBits) != 0)            {                hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits));            }        }        return (hash & 0x7FFFFFFF);    }    /* End Of P. J. Weinberger Hash Function */    /**        * ELF演算法        */    public static int ELFHash(String str)    {        int hash = 0;        int x = 0;        for (int i = 0; i < str.length(); i++)        {            hash = (hash << 4) + str.charAt(i);            if ((x = (int)(hash & 0xF0000000L)) != 0)            {                hash ^= (x >> 24);                hash &= ~x;            }        }        return (hash & 0x7FFFFFFF);    }    /* End Of ELF Hash Function */    /**        * BKDR演算法        */    public static int BKDRHash(String str)    {        int seed = 131; // 31 131 1313 13131 131313 etc..            int hash = 0;        for (int i = 0; i < str.length(); i++)        {            hash = (hash * seed) + str.charAt(i);        }        return (hash & 0x7FFFFFFF);    }    /* End Of BKDR Hash Function */    /**        * SDBM演算法        */    public static int SDBMHash(String str)    {        int hash = 0;        for (int i = 0; i < str.length(); i++)        {            hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;        }        return (hash & 0x7FFFFFFF);    }    /* End Of SDBM Hash Function */    /**        * DJB演算法        */    public static int DJBHash(String str)    {        int hash = 5381;        for (int i = 0; i < str.length(); i++)        {            hash = ((hash << 5) + hash) + str.charAt(i);        }        return (hash & 0x7FFFFFFF);    }    /* End Of DJB Hash Function */    /**        * DEK演算法        */    public static int DEKHash(String str)    {        int hash = str.length();        for (int i = 0; i < str.length(); i++)        {            hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);        }        return (hash & 0x7FFFFFFF);    }    /* End Of DEK Hash Function */    /**        * AP演算法        */    public static int APHash(String str)    {        int hash = 0;        for (int i = 0; i < str.length(); i++)        {            hash ^= ((i & 1) == 0) ? ((hash << 7) ^ str.charAt(i) ^ (hash >> 3)) :                                     (~((hash << 11) ^ str.charAt(i) ^ (hash >> 5)));        }        //       return (hash & 0x7FFFFFFF);            return hash;    }    /* End Of AP Hash Function */    /**        * JAVA自己帶的演算法        */    public static int java(String str)    {        int h = 0;        int off = 0;        int len = str.length();        for (int i = 0; i < len; i++)        {            h = 31 * h + str.charAt(off++);        }        return h;    }    /**        * 混合hash演算法,輸出64位的值        */    public static long mixHash(String str)    {        long hash = str.hashCode();        hash <<= 32;        hash |= FNVHash1(str);        return hash;    }}


 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.