【问题标题】:seeding arc4random() in iOS在 iOS 中播种 arc4random()
【发布时间】:2010-11-23 07:22:21
【问题描述】:

据我所知,arc4random() 生成的随机数比rand() 好得多,但是我还没有看到播种它的方法,我想就像使用 @ 987654323@。有什么办法吗?

【问题讨论】:

  • 你最后找到播种的方法了吗?

标签: ios random arc4random


【解决方案1】:

您实际上可以在 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。
【解决方案2】:

在 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。我错过了什么吗?
  • 我也很困惑为什么 round(_) 在那里。我很困惑为什么你每次电话都播种。
【解决方案3】:

这不是 arc4random 的设计目的。正如文档所述:

arc4random() 函数提供高质量的 32 位伪随机 数字非常快。 arc4random() 种子本身定期来自 random(4)中描述的内核强随机数子系统。

由于它无论如何都是从熵源中重新播种自己,因此手动播种不会获得任何收益,实际上,这种方法并不存在。

【讨论】:

  • 我现在会接受这个答案。看起来没有简单的方法来手动播种 arc4random。 random(4) 中提到手动播种随机设备,但我不清楚我该怎么做。
  • @andrews:你可以做的唯一一件事就是手动将东西插入熵池中,arc4random 从中重新播种。但是,这已被弃用,您仍然无法控制播种。这基本上意味着您不能将 arc4random 视为 PRNG,当使用相同的初始化向量播种时,会产生完全相同的序列。 java.security.SecureRandom 有同样的“问题”,而且设计上也是类似的。如果您需要对 PRNG 进行细粒度控制,请实施 MT-19937,它并不长,而且 C 源代码很容易获得。
  • 实际上,手动播种随机数生成器可以获得一些好处。当与程序生成的资源结合使用时,它提供了一种仅使用其标识种子编号多次复制同一资源的方法。这允许与其他用户共享其他复杂的随机结构,但不需要大数据文件传输。当然,这假设您的伪随机生成器总是为相同的种子生成相同的序列。
  • Ash,这就是 PRNG 的定义。但是,如果您想准确地复制程序生成的资源,那么您最好提供自己的 PRNG,而不是依赖环境提供的 PRNG(可能会改变)。即使您可以手动播种arc4random,它也无济于事,因为它会周期性地重新播种自身,因此无论如何再现性都消失了。
【解决方案4】:

您实际上不需要播种...它会在第一次调用时自行播种。通过调用查看文档

man arc4random

在你的外壳中。描述下的相关行是:

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

【讨论】:

  • 我想播种。有办法吗?
  • @sam 您需要将答案从“您实际上不需要播种...”更改为“您无法播种”。您应该更好地了解并了解播种 SRG 的要求或需要。
【解决方案5】:

您可以使用以下命令将字节序列作为随机性添加到 arc4random:arc4random_addrandom()

http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/arc4random.3.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2013-03-27
    • 2015-10-07
    • 2017-03-23
    • 1970-01-01
    • 2010-11-12
    • 2016-10-14
    相关资源
    最近更新 更多