How to generate a random number is a classic challenge in programming. When we were students, we might know there is no real randomness in the world built on the CPU clock, processes or threads. The randomness comes from given a seed and some magical algorithms. And all of them are pseudo-randomness.

In C, there is a great method to generate a random number, which is called `arc4random`. We can use this method in Swift as well. It returns a random int number. If we need the random number be restricted with in a range, we could do a mod (`%`) calculation. But there is a trap here:

This is wrong code

``````let diceFaceCount = 6
let randomRoll = Int(arc4random()) % diceFaceCount + 1
print(randomRoll)
``````

In fact it runs well in iPhone 5s and later, but in iPhone 5 and earlier, sometimes the program will crash. The worst situation for a developer is this kind of RANDOMNESS. It you cannot regenerate a bug stable, it is hard to say what is wrong with your code.

Good news is this case is quite simple. `Int` in Swift is analogous to `NSInteger`, determined by the architecture of the CPU. On a 32-bit CPU (which happens to be the type of iPhone 5), `Int` means `Int32` in fact, while on 64-bit CPU (iPhone 5s and later), it is `Int64`. The value of `arc4random` returning is not the same, and will be always the type of `UInt32`. As a result, half of the returned values will be overflow when doing `Int` conversion in `Int(arc4random())`, which cause the code crashed in a possibility of 50%.

Actually, we will use another version of `arc4random` method for safety:

``````func arc4random_uniform(_: UInt32) -> UInt32
``````

This version accepts an `UInt32` (`n` for example) as parameter, and normalize the result to a number between 0 and `n - 1`. If we can ensure the input parameter is less than `Int`, the conversion error could be avoided:

``````let diceFaceCount: UInt32 = 6
let randomRoll = Int(arc4random_uniform(diceFaceCount)) + 1
print(randomRoll)
``````

We can set up a method with a `Range` type as input, and returning a random number for later use.

``````func randomInRange(range: Range<Int>) -> Int {
let count = UInt32(range.endIndex - range.startIndex)
return  Int(arc4random_uniform(count)) + range.startIndex
}

for _ in 0...100 {
print(randomInRange(1...6))
}
``````

Further more, we can even design a `Randomable` protocol to extend the random method from `Int` to other types - random string, random element in an array or something else. It is just an exercise for you.