现在的位置: 首页 > 综合 > 正文

Google的CityHash算法

2013年06月16日 ⁄ 综合 ⁄ 共 1174字 ⁄ 字号 评论关闭

在学数据结构的时候,大家一定学过散列表,但很多人不知道算列表有什么用,最后只知道做题,这也许就是教育的悲哀吧。

我开始也不知道,但是有一天,我学java的时候,用到了HashTable和HashSet的时候,就想到了散列表,网上查资料才发现散列表的巨大作用。

言归正传,今天我们来讨论一下字符串哈希算法。常用的简单又高效字符串哈希算有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等。这些算法都是实现比较简单的,对于小数据量一般都可以满足要求,具体实现和性能,请参看网上的介绍。根据这篇文章的介绍,BKDRHash的效果最好,实现也非常的简单,一般的应用可以采用该哈希算法,这里特别给出这个算法的实现吧。

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

如果你看过java中String的hashCode方法的话,你会发现,其算法与BKDRHash算法非常像,可以认为就是一种BKDRHash算法。

    public int hashCode() {
	int h = hash;
	if (h == 0) {
	    int off = offset;
	    char val[] = value;
	    int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }

但是对于一些复杂的应用,或者如果数据量非常大的话,应用这些hash函数就会产生很多碰撞,碰撞的解决办法有多种,比如二次探查或拉链,但这都将影响效率。所以就需要用到复杂一些的哈希函数。有的时候为了安全的考虑,也会用到一些哈希函数,如MD5、SHA1,但这不是我们今天讨论的重点。这些算法复杂度一般会较高,如果仅仅是为减少冲突的话,用MD5和SHA1,或者类似的方法的意义就不是很大。

为了满足大数量的需求,减少碰撞,我们一般需要给出一个64位的哈希,当然前面提到的方法也可以直接用于64位,或者简单改造一下就好。Google在今年的四月份公布了一个叫做CityHash的方法,能比较快的生成一个64位的字符串签名,效率在64位cpu上得到了特殊优化,在工业级应用中可以使用该哈希算法,代码公布在google code上。具体的介绍,可以参看墙内墙外

怎么说呢?谷歌在为计算机技术发展做出了很多重要的贡献,谷歌公开发布的论文,开源的代码都广泛被业界所认可,我们在有意或无意的用着google的很多东西。

抱歉!评论已关闭.