我如何在Swift中生成一个随机的字母数字字符串?
当前回答
来自任何字符集的纯Swift随机字符串。
用法:CharacterSet.alphanumerics。randomString(长度:100)
extension CharacterSet {
/// extracting characters
/// https://stackoverflow.com/a/52133647/1033581
public func characters() -> [Character] {
return codePoints().compactMap { UnicodeScalar($0) }.map { Character($0) }
}
public func codePoints() -> [Int] {
var result: [Int] = []
var plane = 0
for (i, w) in bitmapRepresentation.enumerated() {
let k = i % 8193
if k == 8192 {
plane = Int(w) << 13
continue
}
let base = (plane + k) << 3
for j in 0 ..< 8 where w & 1 << j != 0 {
result.append(base + j)
}
}
return result
}
/// building random string of desired length
/// https://stackoverflow.com/a/42895178/1033581
public func randomString(length: Int) -> String {
let charArray = characters()
let charArrayCount = UInt32(charArray.count)
var randomString = ""
for _ in 0 ..< length {
randomString += String(charArray[Int(arc4random_uniform(charArrayCount))])
}
return randomString
}
}
characters()函数是我所知道的最快的实现。
其他回答
你也可以这样使用它:
extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.characters.count))
randomString += "\(base[base.startIndex.advancedBy(Int(randomValue))])"
}
return randomString
}
}
简单的用法:
let randomString = String.random()
Swift 3语法:
extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.characters.count))
randomString += "\(base[base.index(base.startIndex, offsetBy: Int(randomValue))])"
}
return randomString
}
}
Swift 4语法:
extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.count))
randomString += "\(base[base.index(base.startIndex, offsetBy: Int(randomValue))])"
}
return randomString
}
}
如果你的随机字符串应该是安全随机的,使用这个:
import Foundation
import Security
// ...
private static func createAlphaNumericRandomString(length: Int) -> String? {
// create random numbers from 0 to 63
// use random numbers as index for accessing characters from the symbols string
// this limit is chosen because it is close to the number of possible symbols A-Z, a-z, 0-9
// so the error rate for invalid indices is low
let randomNumberModulo: UInt8 = 64
// indices greater than the length of the symbols string are invalid
// invalid indices are skipped
let symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
var alphaNumericRandomString = ""
let maximumIndex = symbols.count - 1
while alphaNumericRandomString.count != length {
let bytesCount = 1
var randomByte: UInt8 = 0
guard errSecSuccess == SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomByte) else {
return nil
}
let randomIndex = randomByte % randomNumberModulo
// check if index exceeds symbols string length, then skip
guard randomIndex <= maximumIndex else { continue }
let symbolIndex = symbols.index(symbols.startIndex, offsetBy: Int(randomIndex))
alphaNumericRandomString.append(symbols[symbolIndex])
}
return alphaNumericRandomString
}
迅速:
let randomString = NSUUID().uuidString
这是我能想到的最快的解决办法。斯威夫特3.0
extension String {
static func random(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomLength = UInt32(letters.characters.count)
let randomString: String = (0 ..< length).reduce(String()) { accum, _ in
let randomOffset = arc4random_uniform(randomLength)
let randomIndex = letters.index(letters.startIndex, offsetBy: Int(randomOffset))
return accum.appending(String(letters[randomIndex]))
}
return randomString
}
}
SwifterSwift有这个实现
/// SwifterSwift: Create a new random string of given length.
///
/// String(randomOfLength: 10) -> "gY8r3MHvlQ"
///
/// - Parameter length: number of characters in string.
init(randomOfLength length: Int) {
guard length > 0 else {
self.init()
return
}
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString = ""
for _ in 1...length {
randomString.append(base.randomElement()!)
}
self = randomString
}
我做了一些改变,并使用这个实现
static func random(randomOfLength length: Int) -> String {
guard length > 0 else { return "" }
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString = ""
for _ in 1...length {
guard let randomCharacter = base.randomElement() else { continue }
randomString.append(randomCharacter)
}
return randomString
}