良好的哈希函数

时间:2012-01-20 23:34:27

标签: c hashcode hash-function

我一直没能理解哈希函数的设计。我正在经历一个例子。正如您在函数注释中所看到的,为什么要选择31作为要乘的数字。你是如何决定的?这是随机的还是意味着什么?

unsigned int hash(hash_table_t *hashtable, char *str)
{
    unsigned int hashval;

    /* we start our hash out at 0 */
    hashval = 0;

    /* for each character, we multiply the old hash by 31 and add the current
     * character.  Remember that shifting a number left is equivalent to 
     * multiplying it by 2 raised to the number of places shifted.  So we 
     * are in effect multiplying hashval by 32 and then subtracting hashval.  
     * Why do we do this?  Because shifting and subtraction are much more 
     * efficient operations than multiplication.
     */
    for(; *str != '\0'; str++) hashval = *str + (hashval << 5) - hashval;

    /* we then return the hash value mod the hashtable size so that it will
     * fit into the necessary range
     */
    return hashval % hashtable->size;
}

2 个答案:

答案 0 :(得分:3)

有问题的哈希被称为伯恩斯坦哈希,托雷克哈希,或简称为“时代33”哈希。它非常受欢迎,因为它的简单性,速度和使用英语字符串数据的良好分布。

你的评论注意它实际上乘以31,这对你来说似乎是随意的,实际上 有点武断。 Apache Portable Runtime has a comment in their hash algorithm source指出许多可能的常量运作良好(33是最常见的)。它们都是奇数并且接近2的幂,这意味着它们很好地转换为移位和加法或减法。

其他一些有助于理解哈希的资源:

答案 1 :(得分:1)

这是一个有65k视图的哈希函数讲座。在youtube上:http://www.youtube.com/watch?v=KW0UvOW0XIo

这并不是您要求的,但是您的问题表明您对哈希的了解有限。最好阅读教程或检查演示文稿。