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

时间:2014-11-10 13:46:47

标签: string swift

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

22 个答案:

答案 0 :(得分:280)

func randomStringWithLength (len : Int) -> NSString {

    let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

    var randomString : NSMutableString = NSMutableString(capacity: len)

    for (var i=0; i < len; i++){
        var length = UInt32 (letters.length)
        var rand = arc4random_uniform(length)
        randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
    }

    return randomString
}

Swift 3.0更新

func randomString(length: Int) -> String {

    let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let len = UInt32(letters.length)

    var randomString = ""

    for _ in 0 ..< length {
        let rand = arc4random_uniform(len)
        var nextChar = letters.character(at: Int(rand))
        randomString += NSString(characters: &nextChar, length: 1) as String
    }

    return randomString
}

Swift 4.2更新

Swift 4.2在处理随机值和元素方面引入了重大改进。你可以read more about those improvements here。这里的方法简化为几行:

func randomString(length: Int) -> String {
  let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  return String((0..<length).map{ _ in letters.randomElement()! })
}

答案 1 :(得分:56)

这是一个随时可用的解决方案在Swiftier语法中。您只需复制并粘贴它即可:

func randomAlphaNumericString(length: Int) -> String {
    let allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let allowedCharsCount = UInt32(allowedChars.characters.count)
    var randomString = ""

    for _ in 0..<length {
        let randomNum = Int(arc4random_uniform(allowedCharsCount))
        let randomIndex = allowedChars.index(allowedChars.startIndex, offsetBy: randomNum)
        let newCharacter = allowedChars[randomIndex]
        randomString += String(newCharacter)
    }

    return randomString
}

如果您更喜欢具有更强大功能的框架,请随时查看我的项目 HandySwift 。它还包括一个漂亮的随机字母数字字符串解决方案

String(randomWithLength: 8, allowedCharactersType: .alphaNumeric) // => "2TgM5sUG"

答案 2 :(得分:44)

您也可以通过以下方式使用它:

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

答案 3 :(得分:21)

夫特:

DescribeSpotInstanceRequests

答案 4 :(得分:10)

使用 Swift 4.2 ,最好的办法是创建一个包含所需字符的字符串,然后使用randomElement选择每个字符:

let length = 32
let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomCharacters = (0..<length).map{_ in characters.randomElement()!}
let randomString = String(randomCharacters)

我详细介绍了这些变化here

答案 5 :(得分:6)

Swift 2.2版本

// based on https://gist.github.com/samuel-mellert/20b3c99dec168255a046
// which is based on https://gist.github.com/szhernovoy/276e69eb90a0de84dd90
// Updated to work on Swift 2.2

func randomString(length: Int) -> String {
    let charactersString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let charactersArray : [Character] = Array(charactersString.characters)

    var string = ""
    for _ in 0..<length {
        string.append(charactersArray[Int(arc4random()) % charactersArray.count])
    }

    return string
}

基本上调用此方法将生成一个随机字符串,该字符串是传递给函数的整数的长度。要更改可能的字符,只需编辑charactersString字符串即可。也支持unicode字符。

https://gist.github.com/gingofthesouth/54bea667b28a815b2fe33a4da986e327

答案 6 :(得分:6)

简单快速 - UUID()。uuidString

  

//返回从UUID创建的字符串,例如“E621E1F8-C36C-495A-93FC-0C247A3E6E5F”

     

public var uuidString:String {get}

     

https://developer.apple.com/documentation/foundation/uuid

Swift 3.0

let randomString = UUID().uuidString //0548CD07-7E2B-412B-AD69-5B2364644433
print(randomString.replacingOccurrences(of: "-", with: ""))
//0548CD077E2B412BAD695B2364644433

修改

请不要混淆UIDevice.current.identifierForVendor?.uuidString,它不会提供随机值。

答案 7 :(得分:5)

Swift 5.0

// Generating Random String
func randomString(length: Int) -> String {
    let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    return String((0..<length).map{ _ in letters.randomElement()! })
}
// Calling to string
label.text = randomString(length: 3)

答案 8 :(得分:5)

适用于Swift 3.0

func randomString(_ length: Int) -> String {

    let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let len = UInt32(letters.length)

    var randomString = ""

    for _ in 0 ..< length {
        let rand = arc4random_uniform(len)
        var nextChar = letters.character(at: Int(rand))
        randomString += NSString(characters: &nextChar, length: 1) as String
    }

    return randomString
}

答案 9 :(得分:4)

如果您有不寻常的案例

,可能会为某人打字

表现很重要。

这是一个非常简单,清晰,自包含的功能,可以缓存,

(我认为这是你为了简单起见而在全球范围内留下的那种东西。)

func randomNameString(length: Int = 7)->String{

    enum s {
        static let c = Array("abcdefghjklmnpqrstuvwxyz12345789".characters)
        static let k = UInt32(c.count)
    }

    var result = [Character](repeating: "a", count: length)

    for i in 0..<length {
        let r = Int(arc4random_uniform(s.k))
        result[i] = s.c[r]
    }

    return String(result)
}

请注意,这里的要点是针对固定的已知字符集 - 它已缓存。

如果您需要另一个不同的字符集,只需创建另一个缓存函数,

func randomVowelsString(length: Int = 20)->String{
    enum s {
        static let c = Array("AEIOU".characters)
        ...

方便提示:

注意设置&#34; abcdefghjklmnpqrstuvwxyz12345789&#34;避免“坏”。字符

没有0,o,O,i等......人类经常混淆的角色。

这通常用于预订代码等。

答案 10 :(得分:3)

我的更多Swift-ier 问题的实现:

func randomAlphanumericString(length: Int) -> String {

    let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".characters
    let lettersLength = UInt32(letters.count)

    let randomCharacters = (0..<length).map { i -> String in
        let offset = Int(arc4random_uniform(lettersLength))
        let c = letters[letters.startIndex.advancedBy(offset)]
        return String(c)
    }

    return randomCharacters.joinWithSeparator("")
}

答案 11 :(得分:3)

func randomString(length: Int) -> String {
    // whatever letters you want to possibly appear in the output (unicode handled properly by Swift)
    let letters = "abcABC012你好吗∆∌⌘"
    let n = UInt32(letters.characters.count)
    var out = ""
    for _ in 0..<length {
        let index = letters.startIndex.advancedBy(Int(arc4random_uniform(n)))
        out.append(letters[index])
    }
    return out
}

答案 12 :(得分:2)

来自任何String的纯粹Swift随机CharacterSet

用法:CharacterSet.alphanumerics.randomString(length: 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()功能为my fastest known implementation

答案 13 :(得分:2)

响应&#34;我需要随机字符串&#34; 问题(无论用哪种语言)的问题实际上每个解决方案都使用字符串长度的错误主要规范。问题本身很少揭示为什么需要随机字符串,但我会挑战你很少需要随机字符串长度,比如8.你总是需要的是一些唯一字符串,例如,使用作为某种用途的标识符。

有两种主要方法可以获得严格唯一的字符串:确定性(非随机)和存储/比较(这是繁重的)。我们做什么?我们放弃鬼魂。我们改为使用概率唯一性。也就是说,我们接受有一些(但是很小的)风险,我们的字符串不会是唯一的。这是理解collision probabilityentropy有用的地方。

所以我将不变的需求重新定义为需要一些具有较小重复风险的字符串。举一个具体的例子,我们假设你想要产生500万个ID的潜力。您不想存储和比较每个新字符串,并且您希望它们是随机的,因此您接受一些重复的风险。例如,让我们说一万亿次重复的风险小于1。那么你需要多长的弦?那么,这个问题是不明确的,因为它取决于使用的字符。但更重要的是,它被误导了。你需要的是字符串熵的规范,而不是它们的长度。熵可以与某些字符串中重复的概率直接相关。字符串长度可以是

这就是像EntropyString这样的图书馆可以提供帮助的地方。使用EntropyString生成500万字符串中重复次数少于1的随机ID:

import EntropyString

let random = Random()
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
  

&#34; Rrrj6pN4d6GBrFLH4&#34;

EntropyString默认使用32个字符的字符集。还有其他预定义的字符集,您也可以指定自己的字符。例如,使用与上面相同的熵生成ID,但使用十六进制字符:

import EntropyString

let random = Random(.charSet16)
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
  

&#34; 135fe71aec7a80c02dce5&#34;

请注意由于所用字符集中字符总数的不同而导致字符串长度的差异。指定数量的潜在字符串中重复的风险是相同的。字符串长度不是。最重要的是,重复的风险和潜在的字符串数量是明确的。不再猜测字符串长度。

答案 14 :(得分:2)

如果你的随机字符串应该是安全随机的,请使用:

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
}

答案 15 :(得分:1)

已为Swift 4更新。在类扩展名上使用延迟存储的变量。这只会被计算一次。

extension String {

    static var chars: [Character] = {
        return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".map({$0})
    }()

    static func random(length: Int) -> String {
        var partial: [Character] = []

        for _ in 0..<length {
            let rand = Int(arc4random_uniform(UInt32(chars.count)))
            partial.append(chars[rand])
        }

        return String(partial)
    }
}

String.random(length: 10) //STQp9JQxoq

答案 16 :(得分:1)

自由循环,但限制为43个字符。如果需要更多,可以进行修改。与仅使用UUID相比,此方法有两个优点:

  1. 使用小写字母来增强熵,因为UUID()仅生成大写字母
  2. 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

答案 17 :(得分:0)

这是我能想出的 Swift -est解决方案。 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(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
    } 
}

答案 18 :(得分:0)

如果您只需要一个唯一标识符,UUID().uuidString可能符合您的目的。

答案 19 :(得分:0)

SWIFT 4

使用 RandomNumberGenerator 以获得Apple推荐的更好性能

用法: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
    }
}

答案 20 :(得分:0)

对于不想输入整个字符集的人:

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

答案 21 :(得分:-1)

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
}