web-dev-qa-db-de.com

Generieren Sie eine zufällige alphanumerische Zeichenfolge in Swift

Wie generiere ich eine zufällige alphanumerische Zeichenfolge in Swift?

149
vishnu
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 Update

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 Update

Mit Swift 4.2 wurden wichtige Verbesserungen im Umgang mit zufälligen Werten und Elementen eingeführt. Sie können lesen Sie hier mehr über diese Verbesserungen . Hier ist die Methode auf einige Zeilen reduziert:

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

Hier ist eine gebrauchsfertige Lösung in Swiftier-Syntax. Sie können es einfach kopieren und einfügen:

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
}

Wenn Sie ein Framework bevorzugen, das auch mehr nützliche Funktionen bietet, können Sie sich mein Projekt HandySwift ansehen. Es enthält auch eine schöne -Lösung für zufällige alphanumerische Zeichenfolgen:

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

Sie können es auch folgendermaßen verwenden:

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

Einfache Verwendung:

let randomString = String.random()

Swift 3 Syntax:

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 Syntax:

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

Schnell:

let randomString = NSUUID().uuidString
20
Said

Bei Swift 4.2 erstellen Sie am besten eine Zeichenfolge mit den gewünschten Zeichen und verwenden dann randomElement , um jedes Zeichen auszuwählen:

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

Ich gehe auf diese Änderungen näher ein. Hier .

10
leogdion

Swift 2.2 Version

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

Rufen Sie grundsätzlich diese Methode auf, die eine zufällige Zeichenfolge mit der Länge der Ganzzahl generiert, die der Funktion übergeben wird. Um die möglichen Zeichen zu ändern, bearbeiten Sie einfach die Zeichenfolge String. Unterstützt auch Unicode-Zeichen.

https://Gist.github.com/gingofeses/54bea667b28a815b2fe33a4da986e327

6

Einfach und schnell - UUID (). UuidString

// Gibt eine aus der UUID erstellte Zeichenfolge zurück, z. B. "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

EDIT

Bitte verwechseln Sie nicht mit UIDevice.current.identifierForVendor?.uuidString, es werden keine zufälligen Werte angegeben.

6
Jaleel Nazir

für 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
}
5
S1LENT WARRIOR

Könnte jemandem etwas Schreibarbeit ersparen, wenn Sie den ungewöhnlichen Fall haben

leistung zählt.

Hier ist eine extrem einfache, klare, in sich geschlossene Funktion, die

(Ich denke, es ist etwas, was man einfach der globalen Ebene der Einfachheit überlassen würde.)

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

Beachten Sie, dass es sich hier um einen festen, bekannten Zeichensatz handelt - er wird zwischengespeichert.

Wenn Sie einen anderen Zeichensatz benötigen, erstellen Sie einfach eine andere zwischengespeicherte Funktion.

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

Praktischer Tipp:

Beachten Sie, dass der Satz "abcdefghjklmnpqrstuvwxyz12345789" "schlechte" Zeichen vermeidet

Es gibt keine 0, O, O, I ... die Charaktere, die Menschen oft verwechseln.

Dies wird häufig für Buchungscodes usw. durchgeführt.

4
Fattie
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
}
3
Daniel Howard

Mein noch mehr Swift-ier Umsetzung der Frage:

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("")
}
3
Lachezar

Das Problem mit den Antworten auf "Ich benötige zufällige Zeichenfolgen" - Fragen (in welcher Sprache auch immer) ist, dass praktisch jede Lösung eine fehlerhafte Primärspezifikation von string length verwendet. Die Fragen selbst verraten selten, warum die zufälligen Zeichenfolgen benötigt werden, aber ich würde Sie herausfordern, benötigen selten zufällige Längenfolgen, z. B. 8. Was Sie immer brauchen, ist eine Anzahl von unique-Zeichenfolgen, die Sie beispielsweise als Bezeichner verwenden können einen bestimmten Zweck.

Es gibt zwei Hauptmethoden, um Strings eindeutig -Strings zu erhalten: deterministisch (was nicht zufällig ist) und store/compare (was anstrengend ist). Was machen wir? Wir geben den Geist auf. Wir gehen stattdessen mit probabilistischer Einzigartigkeit. Das heißt, wir akzeptieren, dass es ein (wenn auch geringes) Risiko gibt, dass unsere Saiten nicht einzigartig sind. Hier ist das Verstehen von Kollisionswahrscheinlichkeit und Entropie hilfreich.

Ich formuliere also das unveränderliche Bedürfnis so, dass es einige Strings mit einem geringen Wiederholungsrisiko benötigt. Angenommen, Sie möchten ein Potenzial von 5 Millionen IDs generieren. Sie möchten nicht jede neue Zeichenfolge speichern und vergleichen, und Sie möchten, dass sie zufällig sind, so dass Sie das Risiko einer Wiederholung in Kauf nehmen. Nehmen wir als Beispiel an, dass bei einer Billion Wiederholungsmöglichkeit eine Gefahr von weniger als 1 besteht. Welche Länge brauchen Sie also? Nun, diese Frage ist nicht genau festgelegt, da sie von den verwendeten Zeichen abhängt. Aber noch wichtiger ist, dass es falsch ist. Was Sie brauchen, ist eine Angabe der Entropie der Strings, nicht deren Länge. Entropie kann direkt mit der Wahrscheinlichkeit einer Wiederholung in einigen Strings zusammenhängen. Stringlänge kann nicht.

Und hier kann eine Bibliothek wie EntropyString helfen. Um zufällige IDs zu generieren, bei denen die Wahrscheinlichkeit einer Wiederholung in 5 Millionen Zeichenfolgen mit EntropyString geringer als 1 einer Billion ist:

import EntropyString

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

Rrrj6pN4d6GBrFLH4

EntropyString verwendet standardmäßig einen Zeichensatz mit 32 Zeichen. Es gibt andere vordefinierte Zeichensätze, und Sie können auch Ihre eigenen Zeichen angeben. B. IDs mit der gleichen Entropie wie oben erzeugen, jedoch Hex-Zeichen verwenden:

import EntropyString

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

"135fe71aec7a80c02dce5"

Beachten Sie den Unterschied in der Stringlänge aufgrund des Unterschieds in der Gesamtanzahl der Zeichen im verwendeten Zeichensatz. Das Wiederholungsrisiko in der angegebenen Anzahl möglicher Zeichenfolgen ist gleich. Die Stringlängen sind nicht. Und das Beste ist, dass das Wiederholungsrisiko und die mögliche Anzahl von Zeichenfolgen explizit sind. Kein Erraten mehr mit der Stringlänge.

2
dingo sky

Wenn Ihre zufällige Zeichenfolge sicher und zufällig sein soll, verwenden Sie Folgendes:

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

Eine reine Swift-Zufallsvariable String aus einer beliebigen CharacterSet.

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

Die characters()-Funktion ist meine schnellste bekannte Implementierung .

2
Cœur

Schleife frei, jedoch auf 43 Zeichen begrenzt. Wenn Sie mehr benötigen, kann es geändert werden. Dieser Ansatz hat gegenüber der alleinigen Verwendung einer UUID zwei Vorteile:

  1. Größere Entropie durch Verwendung von Kleinbuchstaben, da UUID() nur Großbuchstaben generiert
  2. Ein UUID ist höchstens 36 Zeichen lang (einschließlich der 4 Bindestriche), aber nur 32 Zeichen. Wenn Sie etwas länger brauchen oder keine Bindestriche verwenden möchten, wird dies durch die Verwendung von base64EncodedString erledigt

Diese Funktion verwendet auch einen UInt, um negative Zahlen zu vermeiden.

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

Aufruf in einer Schleife zur Überprüfung der Ausgabe:

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

Was produziert:

Nzk3NjgzMTdBQ0FBNDFCNzk2MDRENzZF
MUI5RURDQzE1RTdCNDA3RDg2MTI4QkQx
M0I3MjJBRjVFRTYyNDFCNkI5OUM1RUVC
RDA1RDZGQ0IzQjI1NDdGREI3NDgxM0Mx
NjcyNUQyOThCNzhCNEVFQTk1RTQ3NTIy
MDkwRTQ0RjFENUFGNEFDOTgyQTUxODI0
RDU2OTNBOUJGMDE4NDhEODlCNEQ1NjZG
RjM2MTUxRjM4RkY3NDU2OUFDOTI0Nzkz
QzUwOTE1N0U1RDVENDE4OEE5NTM2Rjcy
Nzk4QkMxNUJEMjYwNDJDQjhBQkY5QkY5
ODhFNjU0MDVEMUI2NEI5QUIyNjNCNkVF
1
CodeBender

Für Swift 4 aktualisiert. Verwenden Sie eine faule gespeicherte Variable für die Klassenerweiterung. Dies wird nur einmal berechnet.

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
0
Kawin P.

Dies ist die Swift -Test-Lösung, die ich mir vorstellen könnte. 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
    } 
}
0
bojan4

Swift 4

Verwenden von RandomNumberGenerator für eine bessere Leistung als Apple-Empfehlung

Verwendung: String.random(20) Ergebnis: 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
    }
}
0
Jad

Wenn Sie nur eine eindeutige Kennung benötigen, kann UUID().uuidString Ihren Zwecken dienen.

0
man1

Für Leute, die nicht den gesamten Zeichensatz ausschreiben möchten:

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