Last active
January 28, 2023 23:28
-
-
Save szhernovoy/276e69eb90a0de84dd90 to your computer and use it in GitHub Desktop.
Simple random strings generator on Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func randomString(len:Int) -> String { | |
let charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | |
var c = Array(charSet) | |
var s:String = "" | |
for n in (1...10) { | |
s.append(c[Int(arc4random()) % c.count]) | |
} | |
return s | |
} |
This will crash on 32 bit devices on: Int(arc4random())
Swift4+ version
func randomString(of length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var s = ""
for _ in 0 ..< length {
s.append(letters.randomElement()!)
}
return s
}
converting to Array provides 2x performance improvement when generating long strings
e.g. On my Mac (MacBook Pro (16-inch, 2019) 2.3 GHz 8-Core Intel Core i9)
1M random character string generation takes on Average (10 attempts)
- 2 seconds with String based generation
- 1 second with Array based generation
Probably it has to do with the following Complexity note
Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(n), where n is the length of the collection.
in https://developer.apple.com/documentation/swift/array/randomelement()
public func randomString(of length: Int) -> String {
let letters = Array("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
var s = ""
for _ in 0 ..< length {
s.append(letters.randomElement()!)
}
return s
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You need to use .characters.map{ String($0) } to get an array from string in Swift 2.3 and 3.0. Testing in the playground shows this can be very slow and the longer the salt (charSet) the slower it gets. Not sure if it is the most efficient way to do this, but here goes