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 to get away with using random() function. And this worked when i was generating random numbers of a variable size (See code below)
func generateRandomNumber() -> Int
{
var place = 1
var finalNumber = 0;
#if os(Linux)
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
}
And that WORKS. Edit: it works but it gives me the same number every time :(
original pre Linux block of code:
func randomString(_ length: Int) -> String
{
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = UInt32(letters.length)
var randomString = ""
for _ in 0 ..< length {
let rand = arc4random_uniform(len)
var nextChar = letters.character(at: Int(rand))
randomString += NSString(characters: &nextChar, length: 1) as String
}
return randomString
}
And the actual error I get when using above code
error: cannot convert value of type 'NSString' to type 'String' in coercion
randomString += NSString(characters: &nextChar, length: 1) as String
modified for linux block of code.
func randomString(_ length: Int) -> String
{
let letters : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = letters.characters.count
var randomString = ""
#if os(Linux)
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
}
but this time the error is weird it only says Illegal instruction with no extra information. I ran the docker container in interactive mode and i saw my server running and printing out when calling other functions etc.
but the thing is the function actually WORKS when i ran it in IBMs swift sandbox
and I'm assuming its using linux also. Im very stuck and confused any help would be greatly appreciated.
(UPDATE): I ran the same function in just a linux env with a single swift file and not the Vapor swift web framework. and it works. As mentioned in my edit above it gives me the same random string everytime. I will still have to test the entire project once my build finishes. But besides that i need to know if the random() function will actually give me something new each time instead of the same crap.
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With