将一个小数字散列到随机查看的64位整数

时间:2011-12-14 17:45:44

标签: algorithm random hash

我正在寻找一个散列函数,它运行在一个小整数上(比如在0 ... 1000范围内)并输出一个64位的int。

结果集应该看起来像64位整数的随机分布:均匀分布,结果之间没有线性相关。

我希望一个只需要几个CPU周期才能执行的函数。 (代码将使用C ++)。

我考虑将输入乘以一个大素数并取模2 ** 64(类似于线性全等生成器),但输出之间存在明显的依赖关系(在较低位中)。

谷歌搜索没有显示任何内容,但我可能使用错误的搜索字词。

这样的功能是否存在?


一些背景信息:

我想避免在算法中使用带有伪随机数的大型持久表,并在运行中计算随机数字。

安全不是问题。

4 个答案:

答案 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
...     ...                     ...

系列的后续元素之间没有线性相关:

fasthash autocorrelation

两个轴的范围是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。

从数字中减去范围的下限。 将它平方,并将其用作某种位图的直接下标。