From what I can gather arc4random()
generates much better random numbers than rand()
does, however I haven't seen a way to seed it, and I would like to just like using srand()
. Is there a way?
问题:
回答1:
That's not what arc4random is designed to do. As the documentation states:
The
arc4random()
function provides a high quality 32-bit pseudo-random number very quickly.arc4random()
seeds itself on a regular basis from the kernel strong random number subsystem described inrandom(4)
.
Since it is re-seeds itself from an entropy source anyway, you gain nothing by seeding it manually, and in fact, such a method does not exist.
回答2:
You can actually do this in iOS 9.
import GameKit
let source = GKARC4RandomSource(seed: "hello world".data(using: .utf8)!)
source.dropValues(1024)
source.nextInt() // <-- your number
According to the docs:
Arc4 based random sources have repeatable initial sequences. If used for obfuscation you should drop N values from the start, where N should be any number larger than 768 to ensure the initial sequence is flushed.
So as long as you use the same seed data (obviously without using !
in production code) and the same number of dropped values, you'll get the same results.
回答3:
In Swift 3 I'm using srand48()
and drand48()
when I need a seeded value. I made this function that seems to work well enough for my needs:
func seeded_rand(seed:Int, min:Double, max:Double) -> Int
{
srand48(seed)
return Int(round(drand48() * (max-min)) + min)
}
回答4:
You can add a byte sequence as randomness to arc4random by using: arc4random_addrandom()
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/arc4random.3.html
回答5:
You don't actually need to seed it... it seeds itself on the first call. Check out the documentation by calling
man arc4random
in your shell. The relevant line, under DESCRIPTION, is:
There is no need to call arc4random_stir() before using arc4random(),
since arc4random() automatically initializes itself.