Randomness generation with Objective-C and Swift

Randomness is the lack of pattern or predictability. We can be sure of one thing, however: in the closed, digital universe of CPU cycles there is no true randomness, only pseudo randomness.

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 by some initial seed value). Also like hash functions, there are a number of pseudorandom number generators, each of which are optimized for particular performance characteristics: uniformity, periodicity, and computational complexity.

Rather than bore you with any more long-winded treatises on the nature of randomness, we’re going to tackle this in FAQ-style. For more interested readers check out The Art of Computer Programming Vol. 2 Random Numbers.

arc4random() and its related functions are the ones you will need. Specifically, to generate a random number which avoids modulo bias.

How to generate a random int between 0 and N – 1?

NSInteger r = arc4random_uniform(N);

How to generate a random int between 1 and N?

NSInteger r = arc4random_uniform(N) + 1;

How to generate a double between 0 and 1?

If you are generating a random double or float, another good option is the more obscure rand48 family of functions, including drand48(3). Note: rand 48 functions, unlike arc4random functions, require an initial value to be seeded before generating random numbers. This seed function, srand48(3), should only be run once.

srand48(time(0));
double r = drand48();

How do I generate a random character?

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'];

How to pick a random character from an NSString?

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 of man pages. rand is a standard C function and part of the POSIX standard. arc4random is provided on BSD and derived platforms.

  • arc4random does not require an initial seed, making it that much easier to use.
  • arc4random has a range up to 0x100000000 (4294967296), whereas rand and random top out at RAND_MAX = 0x7fffffff (2147483647).
  • rand has often been implemented in a way that regularly cycles low bits, making it more predictable.

tomkausch

Leave a Reply

Your email address will not be published. Required fields are marked *