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?
-
1did you find a way to seed at the end? – Ali Dec 31 '12 at 20:51
5 Answers
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.

- 344,408
- 85
- 689
- 683
-
1I'll accept this answer for now. It looks that there is no easy way to seed manually arc4random. There is mention in random(4) of seeding the random device manually but it's not clear to me how I could do that. – andrewz Nov 24 '10 at 21:57
-
4@andrews: The only thing you *can* do is to manually insert stuff into the entropy pool, from which `arc4random` reseeds. However, that is deprecated and you still don't have control over the seeding. This basically means that you cannot treat `arc4random` as a PRNG which, when seeded with the same initialization vector, yields the exact same sequence. `java.security.SecureRandom` has the same “problem” and it is similarly by design. If you need fine-grained control over your PRNG, then implement MT-19937, it's not long and C source code is readily available. – Joey Nov 25 '10 at 07:22
-
6Actually, there is something to be gained from seeding a random number generator manually. When used in conjunction with procedurally generated resources, it provides a means of reproducing the same resource multiple times with only its identifying seed number. This allows otherwise complex random constructs to be shared with other users, but without the need for large data file transfers. Of course, this assumes your pseudorandom generator always produces the same sequence for the same seed. – Ash Feb 18 '13 at 20:52
-
1Ash, that's the very definition of a PRNG. But if you want to reproduce procedurally-generated resources exactly, then you're much better off providing your own PRNG instead of relying on one provided by the environment (which could change). And even if you could manually seed `arc4random` it wouldn't help because it *re-seeds* itself preiodically, so reproducability is gone anyway. – Joey Feb 19 '13 at 07:16
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.

- 14,831
- 9
- 76
- 80
-
This answer was the easiest for me to implement. It also works in Xamarin. The package to import from has changed from GameKit to GameplayKit. – John Verco Feb 21 '22 at 17:52
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,434
- 3
- 33
- 47
-
Is this really correct when it comes to converting to integer? It seems that border values have less chance to be picked. Assume min is 1 and max is 3: This gives us interval with length of 2 but 3 possible values. When you scale output from random you get a value in range [1, 3] which should be equally distributed. But then interval [1, 1.5] will produce 1; [1.5, 2.5] will produce 2; [2.5, 3] will produce 3. It seems that in this case there is 50% chance of rolling 2 and only 25% to roll 1 or 3. Am I missing something? – Matic Oblak Oct 12 '18 at 08:12
-
I also am confused why round(_) is in there. I am confused why you are seeding on every call, as well. – adazacom Nov 25 '18 at 11:54
You can add a byte sequence as randomness to arc4random by using: arc4random_addrandom()

- 30,736
- 10
- 83
- 104
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.

- 10,988
- 4
- 42
- 53
-
37
-
1@sam you'll need to change your answer from "You don't actually need to seed it..." to "You cannot seed it". You should know better and understand the requirement or need to seed SRG's. – Apr 05 '17 at 23:15