rand(3) / random(3) / arc4random(3) / et al.
Written by Mattt Thompson on
What passes for randomness is merely a hidden chain of causality.
In a mechanical universe of material interactions expressed through mathematical equations, it is unclear whether nature encodes an element of chance, or if it's a uniquely human way to reconcile uncertainty.
We can be sure of one thing, however: in the closed, digital universe of CPU cycles, processes, and threads, there is no true randomness, only pseudorandomness.
Pseudorandomness, is often implemented in a way very similar to a cryptographic hash, as a deterministic function that returns a value based on the current time (salted, of course, by some initial seed value). Also like hash functions, there are a number of PRNG, or pseudorandom number generators, each of which are optimized for particular performance characteristics: uniformity, periodicity, and computational complexity.
Of course, for app developers, all of this is an academic exercise. And rather than bore you with any more highminded, longwinded treatises on the philosophical nature of randomness, we're going to tackle this one FAQstyle.
Our goal this week: to clear up all of the lingering questions and misunderstandings about doing random things in ObjectiveC. Let's dive in!
How Do I Generate a Random Number in ObjectiveC?
tl;dr: Use arc4random()
and its related functions.
Specifically, to generate a random number between
0
and N  1
, use
arc4random_uniform()
, which avoids
modulo bias.
Random int
between 0
and
N  1
NSUInteger r = arc4random_uniform(N);
Random int
between 1
and
N
NSUInteger r = arc4random_uniform(N) + 1;
Random double
between 0
and
1
If you are generating a random double
or
float
, another good option are the more
obscure rand48
family of functions,
including drand48(3)
.
srand48(time(0));
double r = drand48();
rand48
functions, unlikearc4random
functions, require an initial value to be seeded before generating random numbers. This seed function,srand48(3)
, should only be run once.
How Do I Pick a Random Element from an
NSArray
Use arc4random_uniform(3)
to generate a
random number in the range of a nonempty array.
if ([array count] > 0) {
id obj = array[arc4random_uniform([array count])];
}
How Do I Randomly Order an NSArray
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
NSUInteger count = [mutableArray count];
// See http://en.wikipedia.org/wiki/Fisher–Yates_shuffle
if (count > 1) {
for (NSUInteger i = count  1; i > 0; i) {
[mutableArray exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform((int32_t)(i + 1))];
}
}
NSArray *randomArray = [NSArray arrayWithArray:mutableArray];
This code is borrowed from TTTRandomizedEnumerator, which also provides randomized enumerators for
NSSet
,NSOrderedSet
, andNSDictionary
.
How Do I Generate a Random String?
If you're looking to generate "lorem ipsum"style sentences, try constructing a Markov Chain from a corpus.
Otherwise, if you're looking to just get random letters, try one of the following methods:
Generate a Random Lowercase NSString
If you are operating on a known, contiguous range of
Unicode characters, such as the lowercase letters
(U+0061
— U+007A
), you can
do a simple conversion from a char
:
NSString *letter = [NSString stringWithFormat:@"%c", arc4random_uniform(26) + 'a'];
Pick a Random Character From an NSString
Otherwise, a simple way to pick random letters from a set of your choosing is to simply create a string containing all of the possible letters:
NSString *vowels = @"aeiouy";
NSString *letter = [vowels substringWithRange:NSMakeRange(arc4random_uniform([vowels length]), 1)];
Why Should I Use arc4random(3)
instead
of rand(3)
or random(3)
?
C functions are typically denoted with a number
3
inside of parentheses, following the organizational convention ofman
pages.

arc4random
does not require an initial seed (withsrand
orsrandom
), making it that much easier to use. 
arc4random
has a range up to0x100000000 (4294967296)
, whereasrand
andrandom
top out atRAND_MAX = 0x7fffffff (2147483647)
. 
rand
has often been implementated in such a way that regularly cycles low bits, making it more predictable.
What are rand(3)
,
random(3)
, and
arc4random(3)
, and Where Do They Come
From?

rand
is a standard C function. 
random
is defined as part of the POSIX standard. 
arc4random
is provided in BSD and derived platforms.
If you have any additional questions about randomness on ObjectiveC, feel free to tweet @NSHipster. As always, corrections are welcome in the form of a pull request.