strings - swift substring




Generieren Sie eine zufällige alphanumerische Zeichenfolge in Swift (12)

Wie generiert man eine zufällige alphanumerische Zeichenfolge in Swift?


Das Problem mit Antworten auf "Ich brauche zufällige Strings" -Fragen (in welcher Sprache auch immer) ist praktisch jede Lösung verwendet eine fehlerhafte primäre Spezifikation der String-Länge . Die Fragen selbst offenbaren selten, warum die zufälligen Strings benötigt werden, aber ich würde Sie herausfordern, selten zufällige Strings der Länge, sagen Sie 8. Was Sie immer brauchen, ist eine Anzahl von eindeutigen Strings , zum Beispiel als Identifikatoren für einen bestimmten Zweck zu verwenden.

Es gibt zwei Möglichkeiten, strikte eindeutige Strings zu erhalten: deterministisch (was nicht zufällig ist) und speichern / vergleichen (was lästig ist). Was machen wir? Wir geben den Geist auf. Wir gehen stattdessen mit probabilistischer Einzigartigkeit . Das heißt, wir akzeptieren, dass es ein gewisses (wenn auch geringes) Risiko gibt, dass unsere Saiten nicht einzigartig sein werden. Hier hilft das Verständnis von Kollisionswahrscheinlichkeit und entropy .

Ich formuliere also das unveränderliche Bedürfnis als eine Anzahl von Saiten mit einem geringen Wiederholungsrisiko. Als konkretes Beispiel möchten wir sagen, dass Sie ein Potenzial von 5 Millionen IDs generieren möchten. Sie möchten nicht jede neue Zeichenfolge speichern und vergleichen, und Sie möchten, dass sie zufällig sind, so dass Sie ein gewisses Wiederholungsrisiko akzeptieren. Nehmen wir als Beispiel ein Risiko von weniger als 1 in einer Billion Chance auf Wiederholung. Welche Länge der Saite brauchst du? Nun, diese Frage ist unterspezifiziert, da sie von den verwendeten Zeichen abhängt. Aber noch wichtiger ist es fehlgeleitet. Was Sie brauchen, ist eine Spezifikation der Entropie der Strings, nicht ihre Länge. Die Entropie kann direkt mit der Wahrscheinlichkeit einer Wiederholung in einer Anzahl von Strings verbunden sein. Stringlänge kann nicht.

Und hier EntropyString eine Bibliothek wie EntropyString . Um Zufalls-IDs mit weniger als 1 in einer Billion Wiederholungswahrscheinlichkeit in 5 Millionen Strings mithilfe von EntropyString :

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 eigene Zeichen festlegen. Beispiel: Erstellen von IDs mit derselben Entropie wie oben, jedoch mit Hexadezimalzeichen:

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 Zeichenfolgenlänge aufgrund des Unterschieds in der Gesamtzahl der Zeichen im verwendeten Zeichensatz. Das Risiko einer Wiederholung in der angegebenen Anzahl möglicher Zeichenfolgen ist gleich. Die Stringlängen sind nicht. Und das Beste von allem, das Risiko der Wiederholung und die mögliche Anzahl der Strings ist explizit. Kein Raten mehr mit Stringlänge.


Dies ist die schnellste Lösung, die ich mir vorstellen konnte. Schnelles 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
    } 
}

Hier ist eine fertige 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 einige praktische Funktionen bietet, können Sie mein HandySwift Projekt HandySwift . Es enthält auch eine schöne Lösung für zufällige alphanumerische Zeichenfolgen :

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

Könnte jemand ein wenig Tipparbeit sparen, 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 die Art von Dingen, die Sie einfach aus Gründen der Einfachheit auf globaler Ebene verlassen würden.)

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

Tipp, beachten Sie, dass im Beispiel I

vermieden "schlechte" Zeichen

Beachten Sie, dass es keine 0, o, O, i, etc ... "abcdefghjklmnpqrstuvwxyz12345789" gibt, vermeiden Sie die Zeichen, die in den meisten Schriftarten für Menschen leicht zu verwechseln sind. (Dies wird oft bei Buchungscodes usw. getan.)

Beachten Sie, dass der Punkt hier für einen festen, bekannten Zeichensatz ist - er wird zwischengespeichert.

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

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

Schnell:

let randomString = NSUUID().uuidString

Sie können es auch auf folgende Weise 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
    }
}

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

Wenn Sie nur eine eindeutige Kennung benötigen, kann UUID().uuidString Ihre Zwecke UUID().uuidString .


Einfach und schnell - UUID (). UuidString

// Gibt eine aus der UUID erstellte Zeichenfolge zurück, z. B. "E621E1F8-C36C-495A-93FC-0C247A3E6E5F"

Öffentliche Variable uuidString: String {get}

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

Schnelles 3.0

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

BEARBEITEN

Bitte verwechseln Sie nicht mit UIDevice.current.identifierForVendor?.uuidString es wird keine zufälligen Werte geben.


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

Im Grunde rufen Sie diese Methode auf, die eine zufällige Zeichenfolge die Länge der Ganzzahl generiert, die an die Funktion übergeben wird. Um die möglichen Zeichen zu ändern, editieren Sie einfach die Zeichenkettenfolge. Unterstützt auch Unicode-Zeichen.

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


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
}

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
}

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
}




swift