我如何在Swift中生成一个随机的字母数字字符串?


当前回答

func randomUIDString(_ wlength: Int) -> String {

    let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    var randomString = ""

    for _ in 0 ..< wlength {
        let length = UInt32 (letters.length)
        let rand = arc4random_uniform(length)
        randomString = randomString.appendingFormat("%C", letters.character(at: Int(rand)));
    }

    return randomString
}

其他回答

func randomUIDString(_ wlength: Int) -> String {

    let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    var randomString = ""

    for _ in 0 ..< wlength {
        let length = UInt32 (letters.length)
        let rand = arc4random_uniform(length)
        randomString = randomString.appendingFormat("%C", letters.character(at: Int(rand)));
    }

    return randomString
}

免费循环,尽管它被限制在43个字符。如果你需要更多,可以修改。与单独使用UUID相比,这种方法有两个优点:

“更大的熵”使用小写字母,因为UUID()只生成大写字母 UUID最大长度为36个字符(包括4个连字符),不包含连字符的长度为32个字符。你应该需要更长的东西,或不希望连字符包括,使用base64EncodedString处理这个

此外,该函数使用UInt来避免负数。

 func generateRandom(size: UInt) -> String {
        let prefixSize = Int(min(size, 43))
        let uuidString = UUID().uuidString.replacingOccurrences(of: "-", with: "")
        return String(Data(uuidString.utf8)
            .base64EncodedString()
            .replacingOccurrences(of: "=", with: "")
            .prefix(prefixSize))
    }

在循环中调用它来检查输出:

for _ in 0...10 {
    print(generateRandom(size: 32))
}

生产:

Nzk3NjgzMTdBQ0FBNDFCNzk2MDRENzZF
MUI5RURDQzE1RTdCNDA3RDg2MTI4QkQx
M0I3MjJBRjVFRTYyNDFCNkI5OUM1RUVC
RDA1RDZGQ0IzQjI1NDdGREI3NDgxM0Mx
NjcyNUQyOThCNzhCNEVFQTk1RTQ3NTIy
MDkwRTQ0RjFENUFGNEFDOTgyQTUxODI0
RDU2OTNBOUJGMDE4NDhEODlCNEQ1NjZG
RjM2MTUxRjM4RkY3NDU2OUFDOTI0Nzkz
QzUwOTE1N0U1RDVENDE4OEE5NTM2Rjcy
Nzk4QkMxNUJEMjYwNDJDQjhBQkY5QkY5
ODhFNjU0MDVEMUI2NEI5QUIyNjNCNkVF

来自任何字符集的纯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()函数是我所知道的最快的实现。

斯威夫特5.6

此函数生成一个以36为基数的10位数字,然后将其作为字母数字字符串返回。

func randomCode(length: Int) -> String {
    let radix = 36 // = 10 digits + 26 letters
    let number = Int.random(in: 0..<(pow(radix, length)))
    return String(number, radix: radix, uppercase: true)
}

或者如果你不希望代码以“0”开头:

func randomCode(length: Int) -> String {
    let radix = 36 // = 10 digits + 26 letters
    let range = (pow(radix, length)/2)..<(pow(radix, length))
    let number = Int.random(in: range)
    return String(number, radix: radix, uppercase: true)
}

斯威夫特4

苹果推荐使用RandomNumberGenerator获得更好的性能

用法:String.random (20) 结果:CifkNZ9wy9jBOT0KJtV4

extension String{
   static func random(length:Int)->String{
        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        var randomString = ""

        while randomString.utf8.count < length{
            let randomLetter = letters.randomElement()
            randomString += randomLetter?.description ?? ""
        }
        return randomString
    }
}