看到了几个Hash 函数的计算方法,因此想把所见到的所有Hash code 的计算方法的算法罗列出来。会陆续追加看到的Hash 的算法。
第一种: 这是MySql 中计算Hash Code 的一个代码
inline Uint32 Hash( const char* str ){
Uint32 h = 0;
Uint32 len = strlen(str);
while(len >= 4){
h = (h << 5) + h + str[0];
h = (h << 5) + h + str[1];
h = (h << 5) + h + str[2];
h = (h << 5) + h + str[3];
len -= 4;
str += 4;
}
switch(len){
case 3:
h = (h << 5) + h + *str++;
case 2:
h = (h << 5) + h + *str++;
case 1:
h = (h << 5) + h + *str++;
}
return h + h;
}
第二种:这是linux 中计算path hash code 的算法
unsigned long hash (const char * str)
{
unsigned long hs = 0 ;
while(*str) {hs = (hs + (* str << 4) + ( * str ++ >> 4)) * 11 ;}
return hs;
}
int hash(const char * str,int len)
{
int h = 0 ,i ;
for(i = 0 ; i < len ; i ++) ...{
h = h * 31 + str[i];
}
}
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<<r)|(ret>>(32-r));
ret&=0xFFFFFFFFL;
ret^=v*v;
c++;
}
return((ret>>16)^ret);
}
第六种:ELF hash 采用的是 DJB (Daniel J Bernstein) hash
uint32_t dl_new_hash (const char *s)
{
uint32_t h = 5381;
for (unsigned char c = *s; c != '\0'; c = *++s)
h = h * 33 + c;
//h = ((h << 5) + h) + c
return h;
}