# Generating Random Numbers in Swift

Generating (pseudo)random numbers is pretty easy, but there are a few nuances that everyone should know. Generating cryptographically secure random numbers is a bit more difficult, but I'd like to present it too. Let's dive into this random blog post.

## Manny happy returns, C

The most common functions that allow generating random numbers are `arc4random()` and `arc4random_uniform()`. Both come from C and are pretty simple in usage. Though `arc4random()` is not recommended, because it suffers from a condition called modulo bias (some numbers appear more often than others).

```Int(arc4random_uniform(10)) // returns random Int between 0 and 9
Int(arc4random_uniform(10)) + 1 // returns random Int between 1 and 10```

Unfortunately `arc4random_uniform()` returns `UInt32`, so you probably need to cast it to `Int`, which is easier to work with.

You can simply use this function to get i.e. random element of array as well.

`extension Array {  var random: Element? {    guard !isEmpty else { return nil }    return self[Int(arc4random_uniform(UInt32(count)))]  }}`

If you wish to get random `Double`, then you have to use `drand48()`, which returns floating-point number between 0.0 and 1.0.

## GameplayKit

Since iOS 9 there is a cool framework called GameplayKit that also allows generating random numbers. Although the name, it works well not only in games.

```import GameplayKit

let randomSource = GKRandomSource.sharedRandom()
randomSource.nextInt() // returns random Int between Int32.min and Int32.max
randomSource.nextInt(upperBound: 10) // returns random Int between 0 and 9
randomSource.nextUniform() // returns random Float between 0.0 and 1.0
randomSource.nextBool() // returns random Bool```

Looks much better than the old C function, especially when it comes to readability, but in fact it uses `arc4random` function family to return values.

### Roll a dice

I guess it's an example that always appears, but it also looks nice in GameplayKit.

```// This is accessible through GKRandomDistribution.d6() as well
let 🎲 = GKRandomDistribution(forDieWithSideCount: 6)
let roll = 🎲.nextInt()```

It's important to use the same distribution object's instance to get next dice roll result. If you need to roll two or more dices, then you should have an instance of `GKRandomDistribution` for each of them.

### Shuffled distribution

`GKShuffledDistribution` is an interesting class that inherits from `GKRandomDistribution`. It shapes the distribution of random numbers so that you are less likely to get repeats.

It's called fair distribution, because every number will appear an equal number of times. The shuffled distribution makes sure not to repeat any one value until it has used all of its possible values. In a six-sided dice example, if the dice rolls a 1, then another 1 won't be generated for at least five more rolls.

```let 🎲 = GKShuffledDistribution.d6()
(1...100).forEach { _ in print(🎲.nextInt()) }

// could be: 1, 5, 2, 4, 6, 3, 1, 3, 2, 6, 4, 5, 4, 3, 6, 5, 1, 2, …```

### Gaussian distribution

A moment ago I said that you need three `GKRandomDistribution` instances when you're rolling three dices. And that's true. But you can also use the Gaussian distribution.

In the example you get a sum of the result of rolling three six-sided dice.

```let random = GKRandomSource()
let 🎲 = GKGaussianDistribution(randomSource: random,
lowestValue: 3,
highestValue: 18)
let roll = 🎲.nextInt()```

## Pseudo-random, not random

You need to remember that all the examples return pseudo-random numbers. They're fine most of the time, but are not cryptographically robust.

All of them uses a source (also known as seed). Sometimes visible, sometimes not. You can find it easily in `GKGaussianDistribution` initialiser above, but it exists in all `GKRandomDistribution`s.

What it means? All generated numbers are based on the seed. When you know a seed, then you know the whole sequence.

```let seed: UInt64 = 666

let notSoRandomSource1 = GKMersenneTwisterRandomSource(seed: seed)
let 🎲1 = GKRandomDistribution(randomSource: notSoRandomSource1,
lowestValue: 1,
highestValue: 6)
let first = (1...100).map { _ in 🎲1.nextInt() }

let notSoRandomSource2 = GKMersenneTwisterRandomSource(seed: seed)
let 🎲2 = GKRandomDistribution(randomSource: notSoRandomSource2,
lowestValue: 1,
highestValue: 6)
let second = (1...100).map { _ in 🎲2.nextInt() }

let areTheSame = first == second // true```

Does your sequence start with 6, 2, 5, 3, 2, 3, 6, 2, 2, 5 too? That's not a coincidence.

## Cryptographically secure random numbers

As I said before this one is a bit more difficult, but you should definitely use it when security matters.

If you have ever used encrypted Realm database, then probably the code below is not something new for you.

```var bytes = [UInt8](repeating: 0, count: 64)
SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
let key = Data(bytes: bytes)```

It makes usage of Security framework and the default random number generator from the framework. These three lines, eventually give you 64 bytes data object with random numbers inside. It's close to what we need, but how to convert this to get a number?

```let bytesCount = 4
var random: UInt32 = 0
var randomBytes = [UInt8](repeating: 0, count: bytesCount)

SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomBytes)

NSData(bytes: randomBytes, length: bytesCount)
.getBytes(&random, length: bytesCount)

print(random) // prints UInt32 random number```

The code above prints random `UInt32` number. You can safely initialise `Int` with it if you want.

## Still hungry for knowledge?

If yes, then I'm pretty sure this short blog post doesn't reply to all your questions. Feel free to ask me anything, but before let me recommend you two great sources of knowledge for randomising numbers.

Tags

## Read more on our Blog

Check out the knowledge base collected and distilled by experienced professionals.

## We're Netguru

At Netguru we specialize in designing, building, shipping and scaling beautiful, usable products with blazing-fast efficiency.