经典hash函数测试

作者阅读过大量经典软件原代码,下面分别介绍几个经典软件中出现的字符串Hash函数。 
2.1 PHP中出现的字符串Hash函数 
static unsigned long hashpjw(char *arKey, unsigned int nKeyLength) 

unsigned long h = 0, g; 
char *arEnd=arKey+nKeyLength; 

 
while (arKey < arEnd) { 
h = (h << 4) + *arKey++; 
if ((g = (h & 0xF0000000))) { 
h = h ^ (g >> 24); 
h = h ^ g; 


return h; 

2.2 OpenSSL中出现的字符串Hash函数 
unsigned long lh_strhash(char *str) 

int i,l; 
unsigned long ret=0; 
unsigned short *s; 

 
if (str == NULL) return(0); 
l=(strlen(str)+1)/2; 
s=(unsigned short *)str; 
for (i=0; i<l;i++) 
ret^=(s[i]<<(i&0x0f)); 
return(ret); 
} */ 

 
/* The following hash seems to work very well on normal text strings 
* no collisions on /usr/dict/words and it distributes on %2^n quite 
* well, not as good as MD5, but still good. 
*/ 
unsigned long lh_strhash(const char *c) 

unsigned long ret=0; 
long n; 
unsigned long v; 
int r; 

 
if ((c == NULL) || (*c == '/0')) 
return(ret); 
/* 
unsigned char b[16]; 
MD5(c,strlen(c),b); 
return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));  
*/ 

 
n=0x100; 
while (*c) 

v=n|(*c); 
n+=0x100; 
r= (int)((v>>2)^v)&0x0f; 
ret=(ret(32-r)); 
ret&=0xFFFFFFFFL; 
ret^=v*v; 
c++; 

return((ret>>16)^ret); 

在下面的测量过程中我们分别将上面的两个函数标记为OpenSSL_Hash1和OpenSSL_Hash2,至于上面的实现中使用MD5算法的实现函数我们不作测试。 
2.3 MySql中出现的字符串Hash函数 
#ifndef NEW_HASH_FUNCTION 

 
/* Calc hashvalue for a key */ 

 
static uint calc_hashnr(const byte *key,uint length) 

register uint nr=1, nr2=4; 
while (length--) 

nr^= (((nr & 63)+nr2)*((uint) (uchar) *key++))+ (nr << 8); 
nr2+=3; 

return((uint) nr); 


 
/* Calc hashvalue for a key, case indepenently */ 

 
static uint calc_hashnr_caseup(const byte *key,uint length) 

register uint nr=1, nr2=4; 
while (length--) 

nr^= (((nr & 63)+nr2)*((uint) (uchar) toupper(*key++)))+ (nr << 8); 
nr2+=3; 

return((uint) nr); 


 
#else 

 
/* 
* Fowler/Noll/Vo hash 

* The basis of the hash algorithm was taken from an idea sent by email to the 
* IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and 
* Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com) 
* later improved on their algorithm. 

* The magic is in the interesting relationship between the special prime 
* 16777619 (2^24 + 403) and 2^32 and 2^8. 

* This hash produces the fewest collisions of any function that we've seen so 
* far, and works well on both numbers and strings. 
*/ 

 
uint calc_hashnr(const byte *key, uint len) 

const byte *end=key+len; 
uint hash; 
for (hash = 0; key < end; key++) 

hash *= 16777619; 
hash ^= (uint) *(uchar*) key; 

return (hash); 


 
uint calc_hashnr_caseup(const byte *key, uint len) 

const byte *end=key+len; 
uint hash; 
for (hash = 0; key < end; key++) 

hash *= 16777619; 
hash ^= (uint) (uchar) toupper(*key); 

return (hash); 


 
#endif 
Mysql中对字符串Hash函数还区分了大小写,我们的测试中使用不区分大小写的字符串Hash函数,另外我们将上面的两个函数分别记为MYSQL_Hash1和MYSQL_Hash2。 
2.4 另一个经验字符串Hash函数 
unsigned int hash(char *str) 

register unsigned int h; 
register unsigned char *p; 

 
for(h=0, p = (unsigned char *)str; *p ; p++) 
h = 31 * h + *p; 

 
return h; 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值