mysql 字符串的hash函数_经典字符串HASH函数

//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. 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;

}

/*

* The following hash seems to work very well on normal text

strings

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

}

//3.

MySql中出现的字符串Hash函数(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

//4. 一个开源的哈希表源码实现

struct entry

{

void *k, *v;

unsigned int h;

struct entry *next;

};

struct hashtable {

unsigned int tablelength;

struct entry **table;

unsigned int entrycount;

unsigned int loadlimit;

unsigned int primeindex;

unsigned int (*hashfn) (void *k);

int (*eqfn) (void *k1, void *k2);

};

static const unsigned int primes[] = {

53, 97, 193, 389,

769, 1543, 3079, 6151,

12289, 24593, 49157, 98317,

196613, 393241, 786433, 1572869,

3145739, 6291469, 12582917, 25165843,

50331653, 100663319, 201326611, 402653189,

805306457, 1610612741

};

const unsigned int prime_table_length =

sizeof(primes)/sizeof(primes[0]);

const float max_load_factor = 0.65;

struct hashtable *create_hashtable(unsigned int minsize, unsigned

int (*hashf) (void*),

int (*eqf) (void*,void*))

{

struct hashtable *h;

unsigned int pindex, size = primes[0];

/* Check requested hashtable isn't too large */

if (minsize > (1u << 30)) return NULL;

/* Enforce size as prime */

for (pindex=0; pindex < prime_table_length; pindex++)

{

if (primes[pindex] > minsize)

{

size=prime[pindex];

break;

}

}

h = (struct hashtable *)malloc(sizeof(struct hashtable));

if (NULL == h) return NULL; /*oom*/

h->table = (struct entry **)malloc(sizeof(struct entry*) *

size);

if (NULL == h->table)

{

free(h);

return NULL;

} /*oom*/

memset(h->table, 0, size * sizeof(struct entry *));

h->tablelength = size;

h->primeindex = pindex;

h->entrycount = 0;

h->hashfn = hashf;

h->eqfn = eqf;

h->loadlimit = (unsigned int) ceil(size *

max_load_factor);

return h;

}

unsigned int hash(struct hashtable *h, void *k)

{

/* Aim to protect against poor hash functions by adding logic here

- logic taken from java 1.4 hashtable source */

unsigned int i = h->hashfn(k);

i += ~(i << 9);

i ^= ((i >> 14) | (i << 18)); /* >>> */

i += (i << 4);

i ^= ((i >> 10) | (i << 22)); /* >>> */

return i;

}

5. 另一些字符串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;

}

unsigned int hash_func(char *str, int len)

{

register unsigned int sum = 0;

register unsigned int h = 0;

register char *p = str;

while(p - s < len)

{

register unsigned short a = *(p++);

sum ^= a * (p - str);

h ^= a / (p - str);

}

return ((sum << 16) | h) %

MAX_PRIME_LESS_THAN_HASH_LEN;

}

// RS Hash Function

unsigned int RSHash( char *str)

{

unsigned int b = 378551;

unsigned int a = 63689;

unsigned int hash = 0;

while(*str)

{

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

a*= b;

}

return hash&0x7FFFFFFF;

}

// JS Hash Function

unsigned int JSHash( char *str)

{

unsigned int hash = 1315423911;

while( *str)

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

return (hash & 0x7FFFFFFF );

}

// P. J. Weinberger Hash Function

unsigned int PJWHash( char *str)

{

unsigned int BitsInUnignedInt = (unsigned int)( sizeof(unsigned

int)*8 );

unsigned int ThreeQuarters = (unsigned int)( (BitsInUnignedInt*3)/4

);

unsigned int OneEighth = (unsigned int)( BitsInUnignedInt/8

);

unsigned int HighBits = (unsigned int)(0xFFFFFFFF) <<

(BitsInUnignedInt-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 Function ,The mostly frequntly used one

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 Function

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

}

// SDBM Hash Function

unsigned int SDBMHash( char * str)

{

unsigned int hash = 0;

while ( * str)

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

hash;

return (hash & 0x7FFFFFFF);

}

// DJB Hash Function

unsigned int DJBHash( char * str)

{

unsigned int hash = 5381 ;

while ( * str)

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

return (hash & 0x7FFFFFFF );

}

// AP Hash Function

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

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值