In the course of our development, we need to generate some random numbers from time to time. Here we summarize some of the random number generation functions commonly used in swift. Here we will do some sample demonstrations in playground.
Integer random number
If we want a random number of integers, we can consider using the Arc4random series function. We can look at the definition of this function through the man arc4random command:
The Arc4random () function uses the key stream generator employed by the ARC4 cipher, which uses 8*8 8 bit s-boxes. The s-boxes can be inabout (21700) states. The Arc4random () function returns pseudo-random numbers in the range of 0 to (232)-1, and therefore have twice the range of RAND (3) and random (3).
Arc4random uses a key stream generator with ARC4 password encryption (brain fill) to generate a random number of [0, 2^32] intervals (note that the left-closed right-open interval). The return type of this function is UInt32. As shown below:
1 |
arc4random() // 2,919,646,954 |
If we want to generate an integer random number within a specified range, you can use Arc4random ()% Upper_bound, where upper_bound specifies the upper boundary, which is handled as follows:
However, with this method, when the Upper_bound is not a power of 2, a problem of the so-called modulo bias (modulo deviation) is produced.
We have a man arc4random command in the console that allows you to view Arc4random's documentation with one of these:
Arc4random_uniform () would return a uniformly distributed random number less than upper_bound. Arc4random_uniform () is recommended-constructions like ' arc4random ()% upper_bound "as it avoids" modulo bias "when The upper bound is not a power of.
So you can use Arc4random_uniform, which takes a parameter of type UInt32, specifies the upper boundary of a random number interval upper_bound, the function generates a random number range of [0, Upper_bound), as follows:
1 |
arc4random_uniform(10) // 6 |
If you want to specify the minimum value of the interval (such as the random number interval in [5, 100)), you can do the following:
123 |
let max: UInt32 = 100 let min: UInt32 = 5 arc4random_uniform(max - min) + min // 82 |
Of course, the traditional C function rand and random can also be used in Swift. However, there are several drawbacks to these two functions:
Both functions require an initial seed, usually determined at the current time.
The upper limit of these two functions is rand_max=0x7fffffff (2147483647), which is half of arc4random.
Rand functions are implemented in a regular, low-loop manner, which makes it easier to predict
Let's take Rand for example and see how it's used:
123 |
srand(UInt32(time(nil))) // 种子,random对应的是srandom rand() // 1,314,695,483 rand() % 10 // 8 |
64-bit integer random number
In most applications, several of the functions described above are sufficient to satisfy our need for an integer random number. But if we look at their function declarations, we can see that these functions are mainly for the 32-bit integer type. What if we need to generate a 64-bit integer random number? After all, the new machines are now supported by 64-bit.
There seems to be no ready-made function to generate 64-bit random numbers, but Jstn shared his approach on StackOverflow. Let's see it together.
He first defines a generic function, as follows:
12345 |
func arc4random (type: T.Type) -> T { var r: T = 0 arc4random_buf(&r, UInt(sizeof(T))) return r } |
This function uses ARC4RANDOM_BUF to generate random numbers. Let's take a look at the definition of this function through the man ARC4RANDOM_BUF:
Arc4random_buf () function fills the region buf of length nbytes with arc4-derived random data.
This function uses a random number of ARC4 encryption to populate the cache area for the length specified by the second parameter of the function. So, if we pass in sizeof (UInt64), the function generates a random number to fill the 8-byte area and return it to R. Then the 64-bit random number generation method can be implemented as follows:
12345678910111213141516 |
extension UInt64 {
static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {
var
m: UInt64
let u = upper - lower
var
r = arc4random(UInt64)
if
u > UInt64(Int64.max) {
m = 1 + ~u
}
else
{
m = ((max - (u * 2)) + 1) % u
}
while
r < m {
r = arc4random(UInt64)
}
return
(r % u) + lower
}
}
|
Let's try it out:
1 |
UInt64.random() // 4758246381445086013 |
Of course, JSTN also provides the realization of the int64,uint32,int32, we can make a brain repair.
Floating-point random number
If you need a random number for a floating-point value, you can use the DRAND48 function, which produces a floating-point in the [0.0, 1.0] interval. The return value of this function is a double type. Its use is as follows:
12 |
srand48(Int(time(nil))) drand48() // 0.396464773760275 |
Remember that this function is required to first call srand48 to generate a seed initial value.
A small example
Recently wrote a random keyboard, you need to do a random sort of 0-9 of these numbers, just use the above Arc4random function, as follows:
1234 |
let arr = [
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
]
let numbers = arr.sort { (_, _) -> Bool
in
arc4random() < arc4random()
}
|
In closures, two numbers are randomly generated, comparing the sizes between them to determine the collation of the array. It's quite simple.
Summary
In fact, if we look at the API for the C function in Swift, we find that there are many functions related to machine number, such as arc4random_addrandom,erand48 and so on. The above is just a few of the functions we often use, these functions are basically enough. Of course, different scenarios have different needs, and we need to choose the right function according to the actual needs.
The above code has been uploaded to GitHub, the address is random.playground need to refer to.
Reference
Summarize the use of random numbers in Swift