I’m writing an application to pick prize winners for the RubyNation conference that’s coming up here in the Washington DC area. As part of that, I have to generate random numbers. So I went looking for how to generate random numbers in Cocoa. I was looking for something reasonably fast, built-in to Mac OS X, had an easy to use API, and had the most randomness. I defined a random number generation algorithm as being more random if it had a larger range of numbers that it could generate.
The basic usage of a random number generator is something like this:
- Seed (initialize) the random number generator
- Generate a random number
- Modulo the random number against your maximum number to get a number from 0 to your maximum number – 1.
Alright, first off I looked for Objective-C libraries. You know, maybe there was an NSRandom or something like that. There isn’t really one, so I went to look for C functions instead.
Digging into my memory banks, I remembered from my early C days that the standard C library call is srand() with a seed to initialize and then rand() to get the random number. So I looked up srand in the Apple Developer Connection (also known as ADC)
and came up with the laughable description:
rand, rand_r, srand, sranddev — bad random number generator
These interfaces are obsoleted by random(3).
Alright, so onto random. I looked up random in the ADC to see its Mac OS X Manual page. Alright, so it can generate numbers from 0 to (2**31) – 1. You can seed it with srandom() – which could be useful because the same seed will generate the same sequence of random numbers – useful for replaying a game sequence. A better seeding is to use srandomdev() which creates a state array which can’t be guessed by attackers and effectively uses the /dev/random device.
OK that seemed pretty good, but I read on and found this intriguing line:
Applications requiring cryptographic quality randomness should use arc4random(3).
Alright, so now I look up arc4random on ADC. arc4random uses the Alleged RC4 cipher, hence the ARC4. It has a range of 0 to (2**32 – 1), which is twice the range of random. It uses the /dev/urandom device. And best of all, in my opinion, it doesn’t require seeding/initializing since it initializes itself.
So the winner in my book for generating random numbers in Cocoa (really any Objective-C or C program on Mac OS X) is arc4random.