在Swift中生成随机的字母数字字符串

283

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

27个回答

1

Swift 5.6

该函数生成一个 36 进制下的 10 位数字,并将其作为字母数字字符串返回。

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

或者如果你不想让代码以 "0" 开头:

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

0

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
}

0

Swift 5

对于一个合适的强密码生成器,我推荐使用可打印的ASCII字母表以及使用Swift的randomElement()方法。唯一需要包含的变量是密码的长度。

为了使其更加Swifty,我们可以将ASCII字母表存储在String扩展中,不仅仅是为了好玩,而且只需加载到内存一次,然后可以在其他地方使用,因为它具有一定的价值。

extension String {
    static let printableASCII: Set<Character> = [
        " ", "!", "\"", "#", "$", "%", "&", "\'", "(", ")", "*", "+", ",", "-", ".",
        "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=",
        ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
        "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
        "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
        "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
        "z", "{", "|", "}", "~"
    ]
}

func getStrongPassword(ofLength count: Int) -> String {
    var password = String()
    for _ in 0..<count {
        password.append(String.printableASCII.randomElement()!)
    }
    return password
}

print(getStrongPassword(ofLength: 18)) // \g'CeTBRcLguQJ_(*S

请注意,在Swift语言中,printableASCII包含3个转义字符,分别是反斜杠、双引号和单引号。


避免在自动生成的密码中使用元音字母。这样可以减少无意中生成可能冒犯用户的密码的风险。问我怎么知道的。 - HangarRash
@HangarRash 这是一个有趣的限制条件!但是密码也不能像 cupPycakEsprinkleS 这样令人振奋和改变生活的东西。 - trndjc

0

String.shuffeld(length:)函数会对字母表进行洗牌。返回的字符串不会包含重复字符。如果字母表长度小于指定长度,返回的字符串长度将与字母表长度相同。

String.random(length:)函数会返回一个可能包含重复字符且长度为指定长度的字符串。

extension String {
    static func shuffeld(length: Int, alphabet:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") -> String? {
        guard
            alphabet.count > 0
                && length > 0
        else { return nil }
        return alphabet.shuffled().prefix(length).map {String($0)}.joined()
    }
}

extension String {
    static func random(length: Int, alphabet:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") -> String? {
        let a = (0..<length).reduce("") { partialResult, _ in
            partialResult + alphabet
        }
        return shuffeld(length: length, alphabet: a)
    }
}

使用方法:

print(String.shuffeld(length: 15)!)
print(String.shuffeld(length: 3, alphabet: "abcdefg")!)

print(String.random(length: 100)!)
print(String.random(length: 10, alphabet: "☹️")!)

示例输出:

y37Ji8cLsPIQutr 
dcf 
UPfErOiryiuApH3HKHaZl6guY3LwXkmBqyyxqQAIw39lBK2R8mrwtbYKRhL80mZwkV2sf24No9PPXg6uwmUwVljbcUwSVeFBCUdD 
☹️☹️☹️☹️☹️

-1
这是我能想到的最快速的解决方案。Swift 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("") { accum, _ in
            let randomOffset = arc4random_uniform(randomLength)
            let randomIndex = letters.index(letters.startIndex, offsetBy: Int(randomOffset))
            return accum.appending(String(letters[randomIndex]))
        }
    
        return randomString
    } 
}

-1

另一个选项:

extension String {
    static func random(length: Int) -> String {
        guard length > 0 else { return "" }

        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
        let lettersCount = letters.count

        var result = String()
        // Set the initial capacity to improve performance
        result.reserveCapacity(length)

        for _ in 0..<length {
            let randomIndex = Int.random(in: 0..<lettersCount)
            let randomCharacter = letters[String.Index(utf16Offset: randomIndex, in: letters)]
            result.append(randomCharacter)
        }

        return result
    }
}

然后你可以像这样使用它

let randomString = String.random(length: 256)

-2
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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接