我正在寻找一个散列函数,它运行在一个小整数上(比如在0 ... 1000范围内)并输出一个64位的int。
结果集应该看起来像64位整数的随机分布:均匀分布,结果之间没有线性相关。
我希望一个只需要几个CPU周期才能执行的函数。 (代码将使用C ++)。
我考虑将输入乘以一个大素数并取模2 ** 64(类似于线性全等生成器),但输出之间存在明显的依赖关系(在较低位中)。
谷歌搜索没有显示任何内容,但我可能使用错误的搜索字词。
这样的功能是否存在?
一些背景信息:
我想避免在算法中使用带有伪随机数的大型持久表,并在运行中计算随机数字。
安全不是问题。
答案 0 :(得分:7)
我测试了MurmurHash3的64位终结器(由@aix和this SO post建议)。如果输入为零,则该值为零,因此我首先将输入参数增加1:
typedef unsigned long long uint64;
inline uint64 fasthash(uint64 i)
{
i += 1ULL;
i ^= i >> 33ULL;
i *= 0xff51afd7ed558ccdULL;
i ^= i >> 33ULL;
i *= 0xc4ceb9fe1a85ec53ULL;
i ^= i >> 33ULL;
return i;
}
这里输入参数i
是一个小整数,例如{0, 1, ..., 1000}
的元素。输出看起来是随机的:
i fasthash(i) decimal: fasthash(i) hex:
0 12994781566227106604 0xB456BCFC34C2CB2C
1 4233148493373801447 0x3ABF2A20650683E7
2 815575690806614222 0x0B5181C509F8D8CE
3 5156626420896634997 0x47900468A8F01875
... ... ...
系列的后续元素之间没有线性相关:
两个轴的范围是0..2^64-1
答案 1 :(得分:2)
为什么不使用现有的哈希函数,例如MurmurHash3和64位终结器?据作者称,该功能在当前的英特尔硬件上每个密钥需要几十个CPU周期。
答案 2 :(得分:1)
给定:输入i的范围为0到1,000。
const MaxInt,它是cna包含在64位int中的最大值。 (你没有说它是签名还是未签名; 2 ^ 64 = 18446744073709551616)
和函数rand()返回0到1之间的值(大多数语言都有这样的函数)
计算hashvalue = i * rand()*(MaxInt / 1000)
答案 3 :(得分:1)
1,000 * 1,000 = 1,000,000。这非常适合Int32。
从数字中减去范围的下限。 将它平方,并将其用作某种位图的直接下标。