64位乘法散列

时间:2010-11-06 13:30:27

标签: c hash

我正在研究快速的64位哈希。许多现有的安全散列函数太慢了,像FNV这样的非加密散列函数只是不好。

好吧,我想出了类似FNV的哈希:

UINT64 hash=0;

// for each input byte
hash=(hash^(input_byte+1))*HASH_PRIME;

主要问题是关于HASH_PRIME。通常,我们可能会看到乘法散列的“黄金比率”术语。 对于64位散列,黄金比率为0x9e3779b97f4a7c13

我在PRNG中测试了32位黄金比例:

DWORD hash=0;
// loop
hash=(hash^1)*0x9e3779b9;
rnd_out=hash>>24;

此处的良好值可能会产生0xFFFFFFFF的时间 - 即最大可能。这个黄金比例产生明显较小的时期。

或只是

DWORD hash=~0;
// loop
hash*=0x9e3779b9;
rnd_out=hash>>24;

同样,一个足够好的乘数可以产生0x3FFFFFFF个字节的周期。黄金比例在这里产生了更短的时间。

从未测试过64位素数 - 计算量太大。

对我的哈希来说,期间是否重要?在哪里可以找到一个好的64位HASH_PRIMES以及如何测试这些东西?

2 个答案:

答案 0 :(得分:1)

你这样做是为了锻炼吗?否则我会建议看看众所周知的哈希函数,如Bob Jenkin的lookup8和查找系列(http://burtleburtle.net/bob/hash/)和Austin Appleby的杂音http://code.google.com/p/smhasher/(速度杀手和我最喜欢的)。良好的哈希函数很难构建......如果你是滚动类型的哈希,拉宾指纹很难被击败。 如果你真的想要自己动手,确保你的哈希值得体,请使用Appleby和Jenkins哈希测试(折磨和冒烟)

答案 1 :(得分:0)

不确定前两个例子。但是在第三个从代码中获得一个完整的时间段,你需要添加一个奇数。否则,最大周期为65537,可能低至3.甚至可能存在固定点。

无论你在哪里获得0x3FFFFFFF一段时间都不正确。其中一篇Knuth卷过于详细地论述了这一点。

乘数必须是4n + 1的形式,并且必须有一个奇数加数