简述Times33散列函数

闲来无事,随手翻看《Redis5 设计与源码分析》的时候再次看到了哈希函数times33,想着之前在学习PHP源码的时候也看到过这个哈希函数,就想好好研究一下,但是查阅许久都没有找到满意的结果,以下内容部分摘自Laruence介绍PHP中的hash算法的博客,原文地址:http://www.laruence.com/2009/07/23/994.html

PHPHash采用的是目前最为普遍的DJBX33A (Daniel J. Bernstein, Times 33 with Addition), 这个算法被广泛运用与多个软件项目:ApachePerlBerkeley DB等。 对于字符串而言这是目前所知道的最好的哈希算法,原因在于该算法的速度非常快,而且分类非常好(冲突小,分布均匀)。

算法的核心思想就是:hash(i) = hash(i-1) * 33 + str[i]
zend_hash.h中,我们可以找到在PHP中的这个算法:

static inline ulong zend_inline_hash_func(char *arKey, uint nKeyLength)
{
   
    register ulong hash = 5381;
 
    /* variant with the hash unrolled eight times */
    for (; nKeyLength >= 8; nKeyLength -= 8) {
   
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
    }
    switch (nKeyLength) {
   
        case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 3: hash = ((hash 
posted @ 2019-11-02 11:39  寂地烟火  阅读(14)  评论(0)    收藏  举报  来源