我如何在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()函数是我所知道的最快的实现。

其他回答

如果您只需要一个唯一标识符UUID()。uuidString可以满足您的需求。

来自任何字符集的纯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)
}

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
}

一种避免输入整套字符的方法:

func randomAlphanumericString(length: Int) -> String  {
    enum Statics {
        static let scalars = [UnicodeScalar("a").value...UnicodeScalar("z").value,
                              UnicodeScalar("A").value...UnicodeScalar("Z").value,
                              UnicodeScalar("0").value...UnicodeScalar("9").value].joined()

        static let characters = scalars.map { Character(UnicodeScalar($0)!) }
    }
    
    let result = (0..<length).map { _ in Statics.characters.randomElement()! }
    return String(result)
}