各種字串Hash函式比較

2021-06-03 20:59:09 字數 3651 閱讀 7529

文章**自

常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用

位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,

這些函式幾乎不可能找到碰撞。

常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rshash,sdbmhash,

pjwhash,elfhash等等。對於以上幾種雜湊函式,我對其進行了乙個小小的評測。

hash函式

資料1資料2

資料3資料4

資料1得分

資料2得分

資料3得分

資料4得分

平均分bkdrhash

96.55

90.95

82.05

92.64

aphash

96.55

88.46

51.28

86.28

djbhash

96.55

92.31

83.43

jshash

84.62

96.83

17.95

81.94

rshash

51.58

20.51

75.96

sdbmhash

93.1

92.31

57.01

23.08

72.41

pjwhash

43.89

21.95

elfhash

43.89

21.95

其中資料1為100000個字母和數字組成的隨機串雜湊衝突個數。資料2為100000個有意義的英文句

子雜湊衝突個數。資料3為資料1的雜湊值與1000003(大素數)求模後儲存到線性表中衝突的個數。

資料4為資料1的雜湊值與10000019(更大素數)求模後儲存到線性表中衝突的個數。

經過比較,得出以上平均得分。平均數為平方平均數。可以發現,bkdrhash無論是在實際效果還是

編碼實現中,效果都是最突出的。aphash也是較為優秀的演算法。djbhash,jshash,rshash與

sdbmhash各有千秋。pjwhash與elfhash效果最差,但得分相似,其演算法本質是相似的。

在資訊修競賽中,要本著易於編碼除錯的原則,個人認為bkdrhash是最適合記憶和使用的。

cmykrgb123原創,歡迎建議、交流、批評和指正。

附:各種雜湊函式的c語言程式**

unsigned int sdbmhash(char *str)

unsignedint hash = 0;

while(*str)

//equivalent to: hash = 65599*hash + (*str++);

hash= (*str++) + (hash << 6) + (hash << 16) - hash;

return(hash & 0x7fffffff);

// rs hash

unsigned int rshash(char *str)

unsignedint b = 378551;

unsignedint a = 63689;

unsignedint hash = 0;

while(*str)

hash= hash * a + (*str++);

a*= b;

return(hash & 0x7fffffff);

// js hash

unsigned int jshash(char *str)

unsignedint hash = 1315423911;

while(*str)

hash^= ((hash << 5) + (*str++) + (hash >> 2));

return(hash & 0x7fffffff);

// p. j. weinberger hash

unsigned int pjwhash(char *str)

unsignedint bitsinunignedint = (unsigned int)(sizeof(unsigned int) * 8);

unsignedint threequarters   = (unsigned int)((bitsinunignedint  * 3) / 4);

unsignedint oneeighth = (unsigned int)(bitsinunignedint / 8);

unsignedint highbits = (unsigned int)(0xffffffff) << (bitsinunignedint

-oneeighth);

unsignedint hash    = 0;

unsignedint test     = 0;

while(*str)

hash= (hash << oneeighth) + (*str++);

if((test = hash & highbits) != 0)

hash= ((hash ^ (test >> threequarters)) & (~highbits));

return(hash & 0x7fffffff);

// elf hash

unsigned int elfhash(char *str)

unsignedint hash = 0;

unsignedint x = 0;

while(*str)

hash= (hash << 4) + (*str++);

if((x = hash & 0xf0000000l) != 0)

hash^= (x >> 24);

hash&= ~x;

return(hash & 0x7fffffff);

// bkdr hash

unsigned int bkdrhash(char *str)

unsignedint seed = 131; // 31 131 1313 13131 131313 etc..

unsignedint hash = 0;

while(*str)

hash= hash * seed + (*str++);

return(hash & 0x7fffffff);

// djb hash

unsigned int djbhash(char *str)

unsignedint hash = 5381;

while(*str)

hash+= (hash << 5) + (*str++);

return(hash & 0x7fffffff);

// ap hash

unsigned int aphash(char *str)

unsignedint hash = 0;

inti;

for(i=0; *str; i++)

if((i & 1) == 0)

hash^= ((hash << 7) ^ (*str++) ^ (hash >> 3));

else

hash^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));

return(hash & 0x7fffffff);

各種字串hash函式比較

文章 自 常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用 位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有bkdrhash,aphash,djbhash,jsha...

各種字串Hash函式比較

常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rsh...

各種字串Hash函式比較

常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rsh...