最近做了一个Dns日志解析的项目,需要对字符串进行大量查找,对效率要求比较高,所以在网上找了很多关于哈希的资料,
在网上找了一个算法如下:
inline static unsigned int hash_func(char *str, int len)
{
register unsigned int sum = 0;
register unsigned int h = 0;
register unsigned short *p = (unsigned short *)str;
register unsigned short *s = (unsigned short *)str;
while(p - s < len)
{
register unsigned short a = *(p++) * (p-s);
sum += sum ^ a;
h += a;
printf("a = %u\n",a);
}
return ((sum << 16) | h) % MAX_PRIME_LESS_THAN_HASH_LEN;
}
上面这个算法看上去好像是没什么问题,其实这个算法是有问题的,我测试发现,对同一个字符串比如 "OtherCityimg02.taobaocdn.com" 每次哈希的结果不一定一样,
主要是 register unsigned short *p = (unsigned short *)str;
register unsigned short *s = (unsigned short *)str;
导致的,这样p++一次其实是跳了两个字符,所以我做了如下改进:
inline static unsigned int hash_func(char *str, int len)
{
register unsigned int sum = 0;
register unsigned int h = 0;
register unsigned char *p = (unsigned char *)str;
register unsigned char *s = (unsigned char *)str;
while(p - s < len)
{
register unsigned char c = (*(p++));
register unsigned int d = (p-s);
register unsigned int a = ( c * d);
sum += sum ^ a;
h += a;
}
return ((sum << 16) | h) % MAX_PRIME_LESS_THAN_HASH_LEN;
}
现在每次对同一个字符串哈希结果都是一样的了。好,收工!