哈希函数

在大多数实际项目中,对于哈希函数的选择,往往并不怎么在意,讲究的是能用就行,但在性能追求极致的环境里,哈希函数却还是一个考察重点。

在Web服务器lighttpd里,使用的是一个非常流行的DJB hash function,即俗称“Times33”的哈希算法,这个算法很简单,就是不断的乘33。

看实际代码:

  
 
/* the famous DJB hash function for strings */
static uint32_t hashme(buffer *str) {
    uint32_t hash = 5381;
    const char *s;
    for (s = str->ptr; *s; s++) {
        hash = ((hash << 5) + hash) + *s;
    }
 
    hash &= ~(1 << 31); /* strip the highest bit */
 
    return hash;

初始值为什么是5381?看这里:http://stackoverflow.com/questions/10696223/reason-for-5381-number-in-djb-hash-function
结构体buffer的定义如下:

 

typedef struct {
    char *ptr;
 
    size_t used;
    size_t size;
} buffer;

因此,可以看到函数hashme()就是将一个字符串哈希成一个整型值,在很多场景下都有这种需求,比如Hash Map,其key值为字符串(以方便人看懂),而内部实际使用的是整型值(以方便机器操作),在lighttpd这里也是这样,它需要把一个文件路径名转换为一个整型哈希值。

对于一个哈希函数,我们总是期望它有更少的冲突,怎样判断一个哈希函数在冲突方面的好坏,貌似有一个名为avalanche test(雪崩测试)的密码学概念,关于它的具体含义,我暂且也不甚了了,但在nginx的1.0.1里用到了一个名为MurmurHash2算法,据说它有更少的冲突,代码如下:

uint32_t
ngx_murmur_hash2(u_char *data, size_t len)
{
    uint32_t  h, k;
 
    h = 0 ^ len;
 
    while (len >= 4) {
        k  = data[0];
        k |= data[1] << 8;
        k |= data[2] << 16;
        k |= data[3] << 24;
 
        k *= 0x5bd1e995;
        k ^= k >> 24;
        k *= 0x5bd1e995;
 
        h *= 0x5bd1e995;
        h ^= k;
 
        data += 4;
        len -= 4;
    }
 
    switch (len) {
    case 3:
        h ^= data[2] << 16;
    case 2:
        h ^= data[1] << 8;
    case 1:
        h ^= data[0];
        h *= 0x5bd1e995;
    }
 
    h ^= h >> 13;
    h *= 0x5bd1e995;
    h ^= h >> 15;
 
    return h;

  

这个,逻辑真心有点复杂,而且现在已有更进一步的改进版MurmurHash3,嘛,算了,不管它,呵呵。在这里:https://sites.google.com/site/murmurhash/avalanche可以看到一些哈希函数的雪崩测试结果。

转自:http://www.lenky.info/archives/2012/12/2150

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值