Im having 2 problems when trying to generate a random string in Linux with Swift 3.
arc4random_uniform is not available in Linux only on BSD. SO i was able
Swift 4.2, Ubuntu 16.04
let letters : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = letters.count
var randomString:String = ""
for _ in 0 ..< length {
let rand = Int.random(in: 0..<len)
randomString += letters.map { String($0) }[rand]
}
I copied and pasted your code exactly, and it doesn't compile.
fatal error: Can't form a Character from an empty String
// Keep at top of your code (outside of functions)
#if os(Linux)
srandom(UInt32(time(nil)))
#endif
func getRandomNumber(_ min: Int, _ max: Int) -> Int {
#if os(Linux)
return Int(random() % max) + min
#else
return Int(arc4random_uniform(UInt32(max)) + UInt32(min))
#endif
}
func getRandomString(_ chars: String, _ length: Int) -> String {
var str = ""
for _ in 1...length {
str.append(chars.itemOnStartIndex(advancedBy: getRandomNumber(0, chars.count - 1)))
}
return str
}
// Best practice to define this outside of the function itself
let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
print(getRandomString(chars, 10))
This works for me on Ubuntu.
1) Always the same number
You have to set a seed once to get "random" numbers from random()
:
randomSeed(Int(Date().timeIntervalSince1970)
Man page:
If no seed value is provided, the random() function is automatically seeded with a value of 1.
As the seed is always the same (1), you always get the same sequence of "random" numbers.
2) Alphanumeric string
To create your string without using NSString
:
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = UInt32(letters.characters.count)
var randomString = ""
for _ in 0 ..< length {
let rand = myCustomRandom(len)
let randIndex = letters.index(letters.startIndex, offsetBy: Int(rand))
let nextChar = letters[randIndex]
randomString += String(nextChar)
}
return randomString
}
Figured it out.
So the answer to the repeating random number/string was to just add this line before i called the random() function
srand(UInt32(time(nil)))
and I'm assuming thats what fixed the illegal instruction also. Because i don't recall changing anything else.
Needless to say here is my final result
func generateRandomNumber() -> Int
{
var place = 1
var finalNumber = 0;
#if os(Linux)
srand(UInt32(time(nil)))
for _ in 0..<5
{
place *= 10
let randomNumber = Int(random() % 10) + 1
finalNumber += randomNumber * place
}
#else
for _ in 0..<5
{
place *= 10
let randomNumber = Int(arc4random_uniform(10))
finalNumber += randomNumber * place
}
#endif
return finalNumber
}
func randomString(_ length: Int) -> String
{
let letters : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = letters.characters.count
var randomString = ""
#if os(Linux)
srand(UInt32(time(nil)))
for _ in 0..<length
{
let randomValue = (random() % len) + 1
randomString += "\(letters[letters.index(letters.startIndex, offsetBy: Int(randomValue))])"
}
#else
for _ in 0 ..< length
{
let rand = arc4random_uniform(UInt32(len))
randomString += "\(letters[letters.index(letters.startIndex, offsetBy: Int(rand))])"
}
#endif
return randomString
}