哈希算法

时间:2020-03-06 14:39:12  来源:igfitidea点击:

我正在寻找一个散列算法,以创建尽可能接近字符串的唯一散列(最大len = 255),从而产生一个长整数(DWORD)。

我意识到26 ^ 255 >> 2 ^ 32,但是我也知道英语中的单词数远远少于2 ^ 32.

我需要"散列"的字符串主要是单个单词或者一些使用两个或者三个单词的简单构造。

答案:

FNV变体之一应符合要求。它们速度很快,并产生相当均匀的分布式输出。 (由Arachnid答复)

解决方案

有关此问题(及其答案)的先前迭代,请参见此处。

一种技术是使用众所周知的哈希算法(例如MD5或者SHA-1),并且仅使用结果的前32位。

请注意,哈希冲突的风险增加得比我们预期的快。有关此的信息,请阅读有关"生日悖论"的信息。

Ronny Pfannschmidt昨天用通用英语单词进行了测试,并且在Python字符串哈希函数中测试的10000个单词都没有遇到任何冲突。我没有亲自测试过该算法,但是该算法非常简单且快速,并且似乎针对常用单词进行了优化。

这里执行:

static long
string_hash(PyStringObject *a)
{
    register Py_ssize_t len;
    register unsigned char *p;
    register long x;

    if (a->ob_shash != -1)
        return a->ob_shash;
    len = Py_SIZE(a);
    p = (unsigned char *) a->ob_sval;
    x = *p << 7;
    while (--len >= 0)
        x = (1000003*x) ^ *p++;
    x ^= Py_SIZE(a);
    if (x == -1)
        x = -2;
    a->ob_shash = x;
    return x;
}

H(key)= [GetHash(key)+1 +((((GetHash(key)>> 5)+ 1)%(hashsize 1))]%哈希大小

关于HashCodes的MSDN文章

Java的String.hash()可以在此处轻松查看,其算法为

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]