如果我在 5 点或 5:01 拨打 arc4random_uniform(6),我会得到相同的号码吗?

If I called arc4random_uniform(6) at 5 o'clock OR 5:01, would I get the same number?

我正在制作一个 iOS 骰子游戏,一位 Beta 测试员说他喜欢掷骰子已经预先确定的想法,因为我使用 arc4random_uniform(6)。我不确定他们是不是。所以撇开代码 可能 连续选择相同数字的可能性,如果我在 5 或 10 秒内点击骰子,我会生成不同的数字吗?

基本上是随机的。不,它不是基于时间。 Apple 在此处记录了这是如何随机化的:https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/arc4random_uniform.3.html

您的测试人员可能正在考虑软件随机数生成器实际上是 -随机的想法。它们的输出并不是像掷骰子这样的物理过程那样真正随机的:它由生成器保持或给出的某种状态决定。

PRNG 的一个简单实现是 "linear congruential generator":标准库中的函数 rand() 使用了这种技术。它的核心是一个简单的数学函数,每个输出都是通过将前一个输入作为输入来生成的。因此,它需要一个 "seed" 值,并且——这就是您的测试人员的想法——您获得的输出值序列完全由种子值决定。

如果您使用 rand() 创建一个简单的 C 程序,您可以(必须,事实上)使用配套函数 srand()(即 "seed rand")为 LCG 提供一个起始价值。如果您使用常量作为种子值:srand(4),您每次都会以相同的顺序从 rand() 中获得相同的值。

获得任意——注意,不是随机——rand()种子的一种常见方法是使用当前时间:srand(time(NULL))。如果你这样做了,并且足够快地重新播种和生成一个数字,以至于 time() 的 return 没有改变,你确实会看到 rand().[=24= 的相同输出]

这不适用于 arc4random():它不使用 LCG,也不与 rand() 共享此特性。它被认为是* "cryptographically secure";也就是说,它的输出与真实的物理随机性无法区分。

这部分是因为 arc4random() 在您使用它时会自行重新播种 ,并且播种本身是基于 OS。决定输出的状态完全在算法内部;作为普通用户(即,不是攻击者),您不会查看、设置或以其他方式与该状态交互。

所以不,arc4random() 的输出不能可靠地由您 重复 。但是,确实存在可重复的伪随机算法,您当然可以使用它们进行测试。


*维基百科指出,在过去几年中发现了弱点,它可能不再可用于密码学。不过,只要不涉及金钱,您的游戏应该没问题!