Generating random numbers with Swift

SwiftArc4random

Swift Problem Overview


I need to generate a random number.

It appears the arc4random function no longer exists as well as the arc4random_uniform function.

The options I have are arc4random_stir(), arc4random_buf(UnsafeMutablePointer<Void>, Int), and arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32).

I can't find any docs on the functions and no comments in the header files give hints.

Swift Solutions


Solution 1 - Swift

let randomIntFrom0To10 = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 0..<1)

// if you want to get a random element in an array
let greetings = ["hey", "hi", "hello", "hola"]
greetings.randomElement()

Solution 2 - Swift

You could try as well:

let diceRoll = Int(arc4random_uniform(UInt32(6)))

I had to add "UInt32" to make it work.

Solution 3 - Swift

Just call this function and provide minimum and maximum range of number and you will get a random number.

eg.like randomNumber(MIN: 0, MAX: 10) and You will get number between 0 to 9.

func randomNumber(MIN: Int, MAX: Int)-> Int{
    return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN));
}

Note:- You will always get output an Integer number.

Solution 4 - Swift

After some investigation I wrote this:

import Foundation

struct Math {
   private static var seeded = false

   static func randomFractional() -> CGFloat {
  
      if !Math.seeded {
         let time = Int(NSDate().timeIntervalSinceReferenceDate)
         srand48(time)
         Math.seeded = true
      }

      return CGFloat(drand48())
   }
}

Now you can just do Math.randomFraction() to get random numbers [0..1[ without having to remember seeding first. Hope this helps someone :o)

Solution 5 - Swift

Update with swift 4.2 :

let randomInt = Int.random(in: 1..<5)
let randomFloat = Float.random(in: 1..<10)
let randomDouble = Double.random(in: 1...100)
let randomCGFloat = CGFloat.random(in: 1...1000)

Solution 6 - Swift

Another option is to use the xorshift128plus algorithm:

func xorshift128plus(seed0 : UInt64, _ seed1 : UInt64) -> () -> UInt64 {
    var state0 : UInt64 = seed0
    var state1 : UInt64 = seed1
    if state0 == 0 && state1 == 0 {
        state0 = 1 // both state variables cannot be 0
    }

    func rand() -> UInt64 {
        var s1 : UInt64 = state0
        let s0 : UInt64 = state1
        state0 = s0
        s1 ^= s1 << 23
        s1 ^= s1 >> 17
        s1 ^= s0
        s1 ^= s0 >> 26
        state1 = s1
        return UInt64.addWithOverflow(state0, state1).0
    }

    return rand
}

This algorithm has a period of 2^128 - 1 and passes all the tests of the BigCrush test suite. Note that while this is a high-quality pseudo-random number generator with a long period, it is not a cryptographically secure random number generator.

You could seed it from the current time or any other random source of entropy. For example, if you had a function called urand64() that read a UInt64 from /dev/urandom, you could use it like this:

let rand = xorshift128plus(urand64(), urand64())
for _ in 1...10 {
    print(rand())
}

Solution 7 - Swift

let MAX : UInt32 = 9
let MIN : UInt32 = 1 
func randomNumber()
{
   var random_number = Int(arc4random_uniform(MAX) + MIN)
   print ("random = ", random_number);    
}

Solution 8 - Swift

In Swift 3 :

It will generate random number between 0 to limit

let limit : UInt32 = 6
print("Random Number : \(arc4random_uniform(limit))")

Solution 9 - Swift

My implementation as an Int extension. Will generate random numbers in range from..<to

public extension Int {
    static func random(from: Int, to: Int) -> Int {
        guard to > from else {
            assertionFailure("Can not generate negative random numbers")
            return 0
        }
        return Int(arc4random_uniform(UInt32(to - from)) + UInt32(from))
    }
}

Solution 10 - Swift

This is how I get a random number between 2 int's!

func randomNumber(MIN: Int, MAX: Int)-> Int{
    var list : [Int] = []
    for i in MIN...MAX {
        list.append(i)
    }
    return list[Int(arc4random_uniform(UInt32(list.count)))]
}

usage:

print("My Random Number is: \(randomNumber(MIN:-10,MAX:10))")

Solution 11 - Swift

Another option is to use GKMersenneTwisterRandomSource from GameKit. The docs say:

> A deterministic pseudo-random source that generates random numbers > based on a mersenne twister algorithm. This is a deterministic random > source suitable for creating reliable gameplay mechanics. It is > slightly slower than an Arc4 source, but more random, in that it has a > longer period until repeating sequences. While deterministic, this is > not a cryptographic random source. It is however suitable for > obfuscation of gameplay data.

import GameKit

let minValue = 0
let maxValue = 100

var randomDistribution: GKRandomDistribution?
let randomSource = GKMersenneTwisterRandomSource()
randomDistribution = GKRandomDistribution(randomSource: randomSource, lowestValue: minValue, highestValue: maxValue)
let number = randomDistribution?.nextInt() ?? 0
print(number)

Example taken from Apple's sample code: https://github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift

Solution 12 - Swift

I'm late to the party 朗

Using a function that allows you to change the size of the array and the range selection on the fly is the most versatile method. You can also use map so it's very concise. I use it in all of my performance testing/bench marking.

elements is the number of items in the array
only including numbers from 0...max

func randArr(_ elements: Int, _ max: Int) -> [Int] {
        return (0..<elements).map{ _ in Int.random(in: 0...max) }
    }

Code Sense / Placeholders look like this. randArr(elements: Int, max: Int)

10 elements in my array ranging from 0 to 1000.

randArr(10, 1000) // [554, 8, 54, 87, 10, 33, 349, 888, 2, 77]

Solution 13 - Swift

you can use this in specific rate:

let die = [1, 2, 3, 4, 5, 6]
 let firstRoll = die[Int(arc4random_uniform(UInt32(die.count)))]
 let secondRoll = die[Int(arc4random_uniform(UInt32(die.count)))]

Solution 14 - Swift

Lets Code with Swift for the random number or random string :)

let quotes: NSArray = ["R", "A", "N", "D", "O", "M"]
      
      let randomNumber = arc4random_uniform(UInt32(quotes.count))
      let quoteString = quotes[Int(randomNumber)]
      print(quoteString)

it will give you output randomly.

Solution 15 - Swift

Don't forget that some numbers will repeat! so you need to do something like....

my totalQuestions was 47.

func getRandomNumbers(totalQuestions:Int) -> NSMutableArray
{
    
    var arrayOfRandomQuestions: [Int] = []
    
    print("arraySizeRequired = 40")
    print("totalQuestions = \(totalQuestions)")
    
    //This will output a 40 random numbers between 0 and totalQuestions (47)
    while arrayOfRandomQuestions.count < 40
    {
        
        let limit: UInt32 = UInt32(totalQuestions)
        
        let theRandomNumber = (Int(arc4random_uniform(limit)))
        
            if arrayOfRandomQuestions.contains(theRandomNumber)
            {
                print("ping")
                
            }
            else
            {
            //item not found
                arrayOfRandomQuestions.append(theRandomNumber)
            }

    }
    
    print("Random Number set = \(arrayOfRandomQuestions)")
    print("arrayOutputCount = \(arrayOfRandomQuestions.count)")

    
    return arrayOfRandomQuestions as! NSMutableArray
    
}

Solution 16 - Swift

look, i had the same problem but i insert the function as a global variable

as

var RNumber = Int(arc4random_uniform(9)+1)

func GetCase(){

your code
}

obviously this is not efficent, so then i just copy and paste the code into the function so it could be reusable, then xcode suggest me to set the var as constant so my code were

func GetCase() {

let RNumber = Int(arc4random_uniform(9)+1)

   if categoria == 1 {
    }
}
 

well thats a part of my code so xcode tell me something of inmutable and initialization but, it build the app anyway and that advice simply dissapear

hope it helps

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBig_MacView Question on Stackoverflow
Solution 1 - SwiftArsenView Answer on Stackoverflow
Solution 2 - SwiftFernando CardenasView Answer on Stackoverflow
Solution 3 - SwiftPRAVEENView Answer on Stackoverflow
Solution 4 - SwiftMelodiusView Answer on Stackoverflow
Solution 5 - SwiftQuentin NView Answer on Stackoverflow
Solution 6 - SwiftDavid ConradView Answer on Stackoverflow
Solution 7 - SwiftRajesh SharmaView Answer on Stackoverflow
Solution 8 - SwiftMili ShahView Answer on Stackoverflow
Solution 9 - Swiftanatoliy_vView Answer on Stackoverflow
Solution 10 - SwiftIlan SagitalView Answer on Stackoverflow
Solution 11 - SwiftSteve MoserView Answer on Stackoverflow
Solution 12 - SwiftEdisonView Answer on Stackoverflow
Solution 13 - SwiftM.zarView Answer on Stackoverflow
Solution 14 - SwiftAzharhussain ShaikhView Answer on Stackoverflow
Solution 15 - SwiftSlarty BartfastView Answer on Stackoverflow
Solution 16 - SwiftParada11.04View Answer on Stackoverflow