Linux中的Swift arc4random_uniform(max)

时间:2022-01-15 13:28:29

I'm working with Swift in Ubuntu, and I am getting an error that arc4random is an unresolved identifier. More information on this known bug here. Basically, the function only exists in BSD distros. I've tried module mapping header files, apt-getting packages, and I get more and more errors, which is not worth pursuing since this one function is not used very often.

我在Ubuntu中使用Swift,我收到一个错误,arc4random是一个未解析的标识符。这里有关于这个已知错误的更多信息基本上,该功能仅存在于BSD发行版中。我已经尝试过模块映射头文件,apt-getting包,并且我得到越来越多的错误,这是不值得追求的,因为这个函数不经常使用。

Are there any functions to get pseudo random numbers with an upper-bound parameter that is compatible with Swift in Linux?

是否有任何函数可以获得具有与Linux中的Swift兼容的上限参数的伪随机数?

4 个解决方案

#1


5  

If generating a random number within a function, using srandom(UInt32(time(nil))) inside the function can produce the same random number every time.

如果在函数内生成随机数,则在函数内使用srandom(UInt32(time(nil)))可以每次生成相同的随机数。

Instead, prepare the random seed at the top of your main.swift once, and then random should behave as expected throughout.

相反,在main.swift的顶部准备一次随机种子,然后随机应该按预期运行。

Example:

//
//  main.swift
//  Top of your code
//

import Foundation

#if os(Linux)
    srandom(UInt32(time(nil)))
#endif


func getRandomNum(_ min: Int, _ max: Int) -> Int {
    #if os(Linux)
        return Int(random() % max) + min
    #else
        return Int(arc4random_uniform(UInt32(max)) + UInt32(min))
    #endif
}

// Print random numbers between 1 and 10
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))

Swift on Linux (Ubuntu in my case) will produce the same number every time if you put the srandom call inside my getRandomNum function.

如果你把srandom调用放在我的getRandomNum函数中,Swift on Linux(在我的情况下是Ubuntu)每次都会产生相同的数字。

Note of Caution:

srandom and random do not create a "truly" random number, and can be a security concern when making mission-critical applications that would be a target of a hack. The only real solution in that case is to execute Linux's /dev/random directly via Process(), and using its result. But this is outside the scope of the question.

srandom和random不会创建一个“真正的”随机数,并且在制作任务关键型应用程序(可能是黑客攻击目标)时可能会成为安全问题。在这种情况下唯一真正的解决方案是直接通过Process()执行Linux的/ dev / random,并使用其结果。但这超出了问题的范围。

#2


4  

I went with something like this for 4-digit random numbers:

我用4位数的随机数这样的东西:

#if os(Linux)
 srandom(UInt32(time(nil)))
 randomString = String(format: "%04d", UInt32(random() % 10000))
#else
 randomString = String(format: "%04d", Int(arc4random_uniform(10000)))
#endif

Edit: Note that the call to srandom(UInt32(time(nil))) should be outside a function/loop, otherwise it will produce the same value over and over again

编辑:请注意,对srandom的调用(UInt32(time(nil)))应该在函数/循环之外,否则它会一遍又一遍地生成相同的值

#3


2  

You could try something like this?

你可以试试这样的东西吗?

    #if os(Linux)
       random()
    #else
        arc4random_uniform()
    #endif

#4


2  

Swift 4.2

Swift 4.2

let random = Int.random(in: 0...100)

https://developer.apple.com/documentation/swift/int/2995648-random

https://developer.apple.com/documentation/swift/int/2995648-random

PS. It works in Linux.

PS。它适用于Linux。

#1


5  

If generating a random number within a function, using srandom(UInt32(time(nil))) inside the function can produce the same random number every time.

如果在函数内生成随机数,则在函数内使用srandom(UInt32(time(nil)))可以每次生成相同的随机数。

Instead, prepare the random seed at the top of your main.swift once, and then random should behave as expected throughout.

相反,在main.swift的顶部准备一次随机种子,然后随机应该按预期运行。

Example:

//
//  main.swift
//  Top of your code
//

import Foundation

#if os(Linux)
    srandom(UInt32(time(nil)))
#endif


func getRandomNum(_ min: Int, _ max: Int) -> Int {
    #if os(Linux)
        return Int(random() % max) + min
    #else
        return Int(arc4random_uniform(UInt32(max)) + UInt32(min))
    #endif
}

// Print random numbers between 1 and 10
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))
print(getRandomNum(1, 10))

Swift on Linux (Ubuntu in my case) will produce the same number every time if you put the srandom call inside my getRandomNum function.

如果你把srandom调用放在我的getRandomNum函数中,Swift on Linux(在我的情况下是Ubuntu)每次都会产生相同的数字。

Note of Caution:

srandom and random do not create a "truly" random number, and can be a security concern when making mission-critical applications that would be a target of a hack. The only real solution in that case is to execute Linux's /dev/random directly via Process(), and using its result. But this is outside the scope of the question.

srandom和random不会创建一个“真正的”随机数,并且在制作任务关键型应用程序(可能是黑客攻击目标)时可能会成为安全问题。在这种情况下唯一真正的解决方案是直接通过Process()执行Linux的/ dev / random,并使用其结果。但这超出了问题的范围。

#2


4  

I went with something like this for 4-digit random numbers:

我用4位数的随机数这样的东西:

#if os(Linux)
 srandom(UInt32(time(nil)))
 randomString = String(format: "%04d", UInt32(random() % 10000))
#else
 randomString = String(format: "%04d", Int(arc4random_uniform(10000)))
#endif

Edit: Note that the call to srandom(UInt32(time(nil))) should be outside a function/loop, otherwise it will produce the same value over and over again

编辑:请注意,对srandom的调用(UInt32(time(nil)))应该在函数/循环之外,否则它会一遍又一遍地生成相同的值

#3


2  

You could try something like this?

你可以试试这样的东西吗?

    #if os(Linux)
       random()
    #else
        arc4random_uniform()
    #endif

#4


2  

Swift 4.2

Swift 4.2

let random = Int.random(in: 0...100)

https://developer.apple.com/documentation/swift/int/2995648-random

https://developer.apple.com/documentation/swift/int/2995648-random

PS. It works in Linux.

PS。它适用于Linux。