天天看点

mysql 字符串的hash函数_经典字符串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

ret^=(s[i]<

return(ret);

} */

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);

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

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);

}

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

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;

}