C#:从非随机种子生成随机整数

C# : generating random integers from nonrandom seeds

提问人:a52 提问时间:10/3/2023 最后编辑:marc_sa52 更新时间:10/4/2023 访问量:71

问:

我正在制作一个游戏,游戏中的一些物体时不时地需要知道玩家是否移动了。由于涉及的对象数量众多,我没有每帧提醒每个对象,而是将它们分类到包含相应事件的箱中。Bin 1 在玩家移动的第一帧时收到警报,然后 Bin 2 收到第二帧的警报,以此类推,直到某个有限数量。

但是,我需要一些一致的方式来为每个对象分配一个箱。仅使用对象 ID 是行不通的,因为对象的生成方式在其 ID 中给出了模式,这可能会导致某些箱的填充量比其他箱多或少,从而降低了效率的提高。如果所有 ID 都是偶数,并且条柱大小也是偶数,则只会填充偶数条柱。

简而言之,问题在于:

给定一个非随机的、未知的、唯一的整数 S 序列,这些整数可能具有也可能没有模式,我如何选择哈希算法 H 和 bins 数 p 以使 H(S[i]) % p 形成大致均匀的分布?

简单地选择一个质数作为箱数似乎是一个好的开始,但我想知道是否有一种哈希算法可以用来“扰乱”输入序列的模式并提高均匀性。理想情况下,一个已经包含在 .Net 中。

编辑:

在这个答案中找到了一些有希望的结果。不过,我仍然对这个问题感到好奇,无论是从数学的角度来看,还是从.NET中是否包含可以做到这一点的工具。

C# 数学 随机 哈希 加密

评论

0赞 President James K. Polk 10/3/2023
我们在谈论多少个垃圾箱?p 应该有多大?
0赞 a52 10/3/2023
@PresidentJamesK.Polk 目前,大约有 10 个左右。
1赞 Flydog57 10/3/2023
对对象 ID(使用 GetHashCode 或加密哈希)进行哈希处理,然后选取哈希的最后一个十进制或十六进制数字

答:

1赞 Sam Mason 10/4/2023 #1

使用您链接到的其中一种算法可能是一个很好的解决方案。如前所述,该算法对于 64 位整数或 32 位 s 的哈希勘探器链接看起来不错。splitmix64int

你不会说你的“对象 ID”是什么,但如果它们是顺序整数(例如数组索引)或值,这将是这些算法的适当输入。Object.GetHashCode

有一些技术性很强的玩家(例如Minecraft中的SciCraft组)可能能够利用这样的系统,但即使你使用了加密哈希,你也可能需要更多的熵,而不仅仅是那些对象ID。例如,您可以在游戏启动时从操作系统的 CSPRNG 中提取一些状态,并使用对象 ID 对其进行哈希处理。像 MurmurHash 这样的非加密哈希在这样使用时可能会很好。

使用低阶位可能可用于索引您的箱,但我建议使用 2 的幂(例如 8 或 16)作为“按位和”比模/除法便宜得多