设为首页收藏本站官方微博

汉化资料 各种字符串Hash函数比较

[复制链接]
查看: 1658|回复: 0
打印 上一主题 下一主题

[汉化资料] 各种字符串Hash函数比较

跳转到指定楼层
楼主
发表于 2010-5-20 11:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

各种字符串Hash函数比较

原文
+ C6 n3 r. T! E, x% M+ O8 m! chttp://blog.csai.cn/user3/50125/archives/2009/35638.html
# B$ \8 ~8 }, v! |9 L3 |' F9 ]; H1 e& e8 b
[pre]文章转摘自http://www.cmykrgb123.cn/blog/string-hash-compare/
( a3 f) D2 g( K+ A$ r0 z; ^  
, c8 o; R  Z; F常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用 ! u9 c1 o8 l, D! z6 e
位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5和SHA1为代表的杂凑函数, 9 n) d" t9 K7 x$ v
这些函数几乎不可能找到碰撞。   A; S! |4 o0 b3 c. p
常用字符串哈希函数有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash, ) p0 P+ p+ Q) Y  j
PJWHash,ELFHash等等。对于以上几种哈希函数,我对其进行了一个小小的评测。
* D, \8 E) p8 W
Hash函数数据1数据2数据3数据4数据1得分数据2得分数据3得分数据4得分平均分
BKDRHash20477448196.5510090.9582.0592.64
APHash23475449396.5588.4610051.2886.28
DJBHash22497547496.5592.31010083.43
JSHash14476150610084.6296.8317.9581.94
RSHash10486150510010051.5820.5175.96
SDBMHash32484950493.192.3157.0123.0872.41
PJWHash302648785130043.89021.95
ELFHash302648785130043.89021.95
7 R9 J  N% p+ Q! d, G# x
其中数据1为100000个字母和数字组成的随机串哈希冲突个数。数据2为100000个有意义的英文句 . U$ I* J( @4 M
子哈希冲突个数。数据3为数据1的哈希值与1000003(大素数)求模后存储到线性表中冲突的个数。
( W$ w$ M$ w( s" j7 N数据4为数据1的哈希值与10000019(更大素数)求模后存储到线性表中冲突的个数。 * G" M* z/ u; N3 v6 V2 F
经过比较,得出以上平均得分。平均数为平方平均数。可以发现,BKDRHash无论是在实际效果还是 . W: T6 I- q! a1 Z( Z
编码实现中,效果都是最突出的。APHash也是较为优秀的算法。DJBHash,JSHash,RSHash与
; U  e1 `/ u+ W: t1 Q  E) \SDBMHash各有千秋。PJWHash与ELFHash效果最差,但得分相似,其算法本质是相似的。 2 K; ?* A) x9 M. L* X
在信息修竞赛中,要本着易于编码调试的原则,个人认为BKDRHash是最适合记忆和使用的。
% ^) X: v( H/ E4 {0 {* w9 [6 MCmYkRgB123原创,欢迎建议、交流、批评和指正。
5 i: {  g6 J. A6 _! ]  . P) H  y, S+ v. P* Y; ^" S
附:各种哈希函数的C语言程序代码 - q' N: I: E; U4 W/ c
, B3 G6 F4 B" `9 p7 F
unsigned int SDBMHash(char *str)
- k; G& r; m) q# R1 J{ 9 h. T  X4 c1 u" y9 j( U- d' T( k
    unsigned int hash = 0;
/ K4 u& Y  q2 d1 N4 F  
% r8 O. l# c9 N7 [, f0 j    while (*str) 7 w7 o! E* M( A+ p
    { . Y) n6 _  U! R( E" {
        // equivalent to: hash = 65599*hash + (*str++); 4 c8 ]0 p5 ?- c/ G, @6 {$ S# j
        hash = (*str++) + (hash << 6) + (hash << 16) - hash; / ^# [8 c  r6 z
    }
! ^9 H; Z6 E; @+ R, H; L  
; D) {  L  K0 G    return (hash & 0x7FFFFFFF);
4 O1 G' P' {2 n2 U  ^' q2 u+ u+ ?} , \* b& h# `9 j# L9 k" e
    D, U* s  N8 `! ?8 o( h
// RS Hash ' n: O1 |- \" r2 ]. Q( I
unsigned int RSHash(char *str)
& K6 f9 {. O' a) v: `{
9 u9 p: x8 G8 }2 `/ ~" S; n$ Q5 O  I    unsigned int b = 378551;
4 f# L* l. r: {, I3 N    unsigned int a = 63689;
: L( e8 m. M7 J8 w6 m) Y9 T9 {    unsigned int hash = 0; 5 e5 }5 \/ _0 ^; U
  6 s$ ^7 r4 j: q+ u3 n
    while (*str)
8 x0 s5 {: J0 C* P    {
  e% I! @! X% [2 o        hash = hash * a + (*str++);
3 u% `! D* J+ W* J% _' ^        a *= b; 7 B' C( p$ L; J+ _9 c, k
    }
- l2 M4 e+ r; ?4 e- t  ! H5 n8 I; X3 N* q/ V
    return (hash & 0x7FFFFFFF);
3 B  e9 H: X( V4 s6 j} 4 _1 f& H0 N% Y( _
  # j3 S8 ?* s: `4 s# o
// JS Hash
# Q7 l8 n" E, G) P) g0 k6 W1 i# funsigned int JSHash(char *str) * Y4 ~8 |& n0 ?) L. `2 N
{
( e" H5 ?1 H  m2 ^9 {+ }    unsigned int hash = 1315423911; 6 T# h4 q! U1 b+ _9 K( ]$ P; z& f
  
  {$ ^. G. K: c% C9 R    while (*str)
' M  q) M8 _  G    { ' @6 E- f$ h1 f7 X4 \
        hash ^= ((hash << 5) + (*str++) + (hash >> 2)); , T2 e4 l2 n! ~
    }
  g& |) g! ?8 T, n/ J- o  
" W% H0 ]! i5 H4 [    return (hash & 0x7FFFFFFF); ! s% D7 y2 r! Z
}
7 Q* k( I. v- [3 W5 ~  
3 s' s0 h- i9 Q! I// P. J. Weinberger Hash - L4 O4 ]* I4 g, m* o# b4 I
unsigned int PJWHash(char *str): |7 b7 s: @7 ?3 Q. K1 V3 x8 j+ L
{+ N: U7 A% {+ p# ]
    unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 8);
- h1 ^1 ^" [% A$ a- S3 b    unsigned int ThreeQuarters    = (unsigned int)((BitsInUnignedInt  * 3) / 4);
+ H' e9 E, a4 Z( @    unsigned int OneEighth = (unsigned int)(BitsInUnignedInt / 8);) J7 p  s% E% L# a  q1 ^/ }
    unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnignedInt [pre]                                               - 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 & 0x7FFFFFFF);} // ELF Hash 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 & 0x7FFFFFFF);} // BKDR Hash 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 & 0x7FFFFFFF);} // DJB Hash unsigned int DJBHash(char *str){    unsigned int hash = 5381;     while (*str)    {        hash += (hash << 5) + (*str++);    }     return (hash & 0x7FFFFFFF);} // AP Hash 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 & 0x7FFFFFFF);}[/pre]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

冒险解谜游戏中文网 ChinaAVG

官方微博官方微信号小黑屋 微信玩家群  

(C) ChinaAVG 2004 - 2019 All Right Reserved. Powered by Discuz! X3.2
辽ICP备11008827号 | 桂公网安备 45010702000051号

冒险,与你同在。 冒险解谜游戏中文网ChinaAVG诞生于2004年9月9日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

快速回复 返回顶部 返回列表