在iOS中使用arc4random()生成随机数的种子

26
据我所了解,arc4random() 生成的随机数要比 rand() 生成的随机数好得多,但是我还没有找到种子的方法,我想像使用 srand() 一样使用它。有办法吗?

1
你找到在结尾处进行种子播种的方法了吗? - Ali
5个回答

24

arc4random的设计并非如此。正如文档所述:

arc4random()函数可以快速提供高质量的32位伪随机数。arc4random()会定期从内核强随机数子系统(random(4))中获取种子。

由于它已经从熵源重新进行了种子生成,因此手动设置种子没有任何意义,实际上这种方法不存在。


1
我现在会接受这个答案。看起来手动种子arc4random没有简单的方法。在random(4)中提到手动种植随机设备,但我不清楚如何做到这一点。 - andrewz
4
@andrews:你唯一能做的就是手动将内容插入熵池,arc4random 会从中重新生成种子。然而,这已经被弃用,并且你仍然无法控制种子生成。这基本上意味着你不能将 arc4random 视为一个 PRNG,即当使用相同的初始化向量进行种子化时,它会产生完全相同的序列。java.security.SecureRandom 存在同样的“问题”,这也是设计如此。如果需要对 PRNG 进行细粒度控制,则可以实现 MT-19937,它的 C 源代码很短,而且可轻松获得。 - Joey
7
手动设置随机数生成器的种子是有益的。当与程序生成资源一起使用时,它提供了一种用唯一的种子号多次复制同一资源的方式。这使得即使是复杂的随机结构也可以与其他用户共享,而无需进行大量的数据文件传输。当然,前提是您的伪随机生成器在相同的种子下总是产生相同的随机数序列。 - Ash
1
Ash,这就是PRNG的定义。但是,如果您想要精确地复制程序生成的资源,那么最好提供自己的PRNG,而不是依赖于环境提供的PRNG(因为环境可能会改变)。即使您可以手动设置arc4random的种子,它也无济于事,因为它会定期重新生成种子,所以再现性已经消失了。 - Joey

8

在iOS 9中,您实际上可以做到这一点。

import GameKit

let source = GKARC4RandomSource(seed: "hello world".data(using: .utf8)!)
source.dropValues(1024)
source.nextInt() // <-- your number

根据文档:
基于Arc4的随机源具有可重复的初始序列。如果用于混淆,您应该从开始处删除N个值,其中N应该是大于768的任何数字,以确保初始序列被清除。
只要使用相同的种子数据(显然不在生产代码中使用)和相同数量的删除值,就会得到相同的结果。

这个答案对我来说是最容易实现的。它在Xamarin中也可以工作。要导入的包已从GameKit更改为GameplayKit。 - John Verco

6

在Swift 3中,当我需要一个种子值时,我使用srand48()drand48()。我创建了这个函数,它似乎对我的需求足够好:

func seeded_rand(seed:Int, min:Double, max:Double) -> Int
{
    srand48(seed)
    return Int(round(drand48() * (max-min)) + min)
}

在将其转换为整数时,这真的正确吗?似乎边界值的选择机会较小。假设最小值为1,最大值为3:这给我们一个长度为2但有3个可能值的区间。当你从随机输出中缩放输出时,你会得到一个在[1, 3]范围内的值,应该是均匀分布的。但是,然后区间[1,1.5]将产生1;[1.5,2.5]将产生2;[2.5,3]将产生3。在这种情况下,似乎有50%的机会掷出2,而只有25%的机会掷出1或3。我错过了什么吗? - Matic Oblak
我也不明白为什么要在里面加上 round(_)。而且我也不明白为什么你每次都要重新生成种子。 - adazacom

1

-1

你实际上不需要手动进行种子操作... 它会在第一次调用时自动进行。通过调用文档来查看更多信息。

man arc4random

在你的shell中,相关的行,在DESCRIPTION下面:

There is no need to call arc4random_stir() before using arc4random(),
since arc4random() automatically initializes itself.

37
我想播种它。有办法吗? - andrewz
1
@sam,你需要将你的回答从“实际上你不需要播种它...”改为“你不能播种它”。你应该更好地了解并理解播种SRG的要求或需求。 - user1068477

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接