C# 在Int32或UInt32中,有哪些好的散列位方法?

C# 在Int32或UInt32中,有哪些好的散列位方法?,c#,bit-manipulation,prng,C#,Bit Manipulation,Prng,我有一个伪随机数生成器的实现,特别是George Marsaglia的XOR Shift RNG。我的实施是: 事实证明,第一个随机样本与种子非常密切相关,如果您看一下重新初始化(int-seed)方法,这是非常明显的。这很糟糕。我建议的解决方案是按如下方式混合种子: _x = (uint)( (seed * 2147483647) ^ ((seed << 16 | seed >> 48) * 28111) ^ ((se

我有一个伪随机数生成器的实现,特别是George Marsaglia的XOR Shift RNG。我的实施是:

事实证明,第一个随机样本与种子非常密切相关,如果您看一下重新初始化(int-seed)方法,这是非常明显的。这很糟糕。我建议的解决方案是按如下方式混合种子:

_x = (uint)(  (seed * 2147483647) 
           ^ ((seed << 16 | seed >> 48) * 28111) 
           ^ ((seed << 32 | seed >> 32) * 69001)
           ^ ((seed << 48 | seed >> 16) * 45083));
我可能会用更少的素数/乘法。两个看起来太少了(我仍然可以在第一个样本中看到模式),三个看起来还可以,所以为了安全边际,我把它设为四个

==更新2===

仅供参考,上述内容减少至功能等效:

_x = seed * 3575866506U;

起初我没有发现这一点,当我发现时,我想知道在计算的不同阶段溢出是否会导致不同的结果。我相信答案是否定的——这两种计算总是给出相同的答案。

根据一些研究人员的说法,它们是目前可用的最好的非加密散列算法,既快速、简单,又具有良好的统计性能

有关更多信息,请访问


编辑:截至2021年5月,floodberry.com指向非加密哈希函数Zoo的链接无效。内容仍然可以在上找到。

如果在一个时钟周期内初始化多个RNG(这是我有时遇到的问题),那么使用时钟也是不好的。您可以扔掉第一个值,或者可能是由时钟随机确定的前n个值吗?请参阅Marsaglia,George。(2003). Xorshift RNGs。如果你在寻找32位散列函数,你可能想看看这篇文章:你的(滞后斐波那契混合)异或移位生成器使用三元组8,11,19,它没有最大周期(你可能想使用9,11,19?)。此外,移位异或操作似乎有点奇怪
t
(又称
x
)与自身的两个移位值异或,即与
w
w
的移位值异或。通常情况下,应该将一个值与相应临时值的移位值异或三次。我不确定你所做的是否是等效的。链接已经失效,谷歌也没有任何明显的镜像。
_x = seed * 3575866506U;