Jak wygenerować losowy ciąg alfanumeryczny w Swift?
208
Aktualizacja Swift 4.2
Swift 4.2 wprowadził znaczną poprawę w radzeniu sobie z losowymi wartościami i elementami. Możesz przeczytać więcej o tych ulepszeniach tutaj . Oto metoda zredukowana do kilku wierszy:
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
Aktualizacja 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
}
Oryginalna odpowiedź:
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
}
Oto gotowe do użycia rozwiązanie w składni Swiftier . Możesz go po prostu skopiować i wkleić:
Jeśli wolisz Framework, który ma również kilka przydatnych funkcji, możesz sprawdzić mój projekt HandySwift . Zawiera również piękne rozwiązanie dla losowych ciągów alfanumerycznych :
źródło
Możesz użyć go również w następujący sposób:
Proste użycie:
Składnia Swift 3:
Składnia Swift 4:
źródło
Szybki:
źródło
AKTUALIZACJA 2019.
W niezwykłym przypadku to
wydajność ma znaczenie.
Oto niezwykle przejrzysta funkcja buforująca :
Dzieje się tak, gdy masz ustalony, znany zestaw znaków.
Przydatna wskazówka:
Zauważ, że „abcdefghjklmnpqrstuvwxyz12345789” unika „złych” znaków
Nie ma 0, o, O, i itd. ... ludzie często mylą.
Odbywa się to często w przypadku kodów rezerwacji i podobnych kodów, które będą używane przez klientów.
źródło
repeating:count:
.Prosty i szybki - UUID (). UuidString
Swift 3.0
EDYTOWAĆ
Proszę nie mylić z
UIDevice.current.identifierForVendor?.uuidString
tym, że nie da losowych wartości.źródło
W Swift 4.2 najlepiej jest utworzyć ciąg znaków z wybranymi postaciami, a następnie użyć randomElement, aby wybrać każdą postać:
Więcej szczegółów na temat tych zmian tutaj .
źródło
Wersja Swift 2.2
Zasadniczo wywołaj tę metodę, która wygeneruje losowy ciąg długości całkowitej liczby całkowitej przekazanej funkcji. Aby zmienić możliwe znaki, po prostu edytuj ciąg znakówString. Obsługuje również znaki Unicode.
https://gist.github.com/gingofthesouth/54bea667b28a815b2fe33a4da986e327
źródło
EXC_BAD_INSTRUCTION
let random = randomString(16)
. EXC był tylko na prawdziwym urządzeniu i nie widziałem go w symulatorze i był przerywany na urządzeniu.random % count
nie nie (zawsze) stworzyć jednolitą dystrybucję. Jeśli jest to istotne dla Ciebie, poszukaj innych odpowiedzi, które wykorzystująarc4random_uniform()
.Dla osób, które nie chcą wpisywać całego zestawu znaków:
źródło
dla Swift 3.0
źródło
Czysty losowy
String
z dowolnegoCharacterSet
.Stosowanie:
CharacterSet.alphanumerics.randomString(length: 100)
Ta
characters()
funkcja jest moją najszybszą znaną implementacją .źródło
źródło
Moja jeszcze szybsza implementacja pytania:
źródło
Bez pętli, choć jest ograniczona do 43 znaków. Jeśli potrzebujesz więcej, możesz je zmodyfikować. Podejście to ma dwie zalety w porównaniu z wykorzystaniem wyłącznie UUID:
UUID()
generuje tylko duże literyUUID
wynosi maksymalnie 36 znaków (w tym 4 łączniki), ale bez nich tylko 32 znaki. Jeśli potrzebujesz czegoś dłuższego lub nie chcesz dołączać łączników, skorzystaj zbase64EncodedString
uchwytówPonadto funkcja ta wykorzystuje a,
UInt
aby uniknąć liczb ujemnych.Wywołanie go w pętli w celu sprawdzenia wyjścia:
Który produkuje:
źródło
Swift 5.0
źródło
Problem z odpowiedziami na pytania „Potrzebuję losowych ciągów” (w dowolnym języku) polega na tym, że praktycznie każde rozwiązanie wykorzystuje wadliwą podstawową specyfikację długości łańcucha . Same pytania rzadko ujawniają, dlaczego potrzebne są losowe ciągi, ale rzuciłbym wyzwanie, że rzadko potrzebujesz losowych ciągów, powiedzmy 8. To, czego zawsze potrzebujesz, to pewna liczba unikatowych ciągów , na przykład do użycia jako identyfikatory w jakimś celu.
Istnieją dwa wiodące sposoby uzyskania ściśle unikatowych ciągów: deterministycznie (co nie jest losowe) i przechowywanie / porównywanie (co jest uciążliwe). Co robimy? Porzucamy ducha. Idziemy z probabilistycznego wyjątkowości zamiast. To znaczy, akceptujemy, że istnieje pewne (choć niewielkie) ryzyko, że nasze łańcuchy nie będą unikalne. To tutaj rozumiemy prawdopodobieństwo kolizji i entropię pomocne .
Dlatego zmienię niezmienną potrzebę jako wymagającą pewnej liczby ciągów z niewielkim ryzykiem powtórzenia. Jako konkretny przykład załóżmy, że chcesz wygenerować potencjał 5 milionów identyfikatorów. Nie chcesz przechowywać i porównywać każdego nowego łańcucha i chcesz, aby były losowe, więc akceptujesz ryzyko powtórzenia. Jako przykład, powiedzmy, że ryzyko jest mniejsze niż 1 przy trylionach szansy na powtórzenie. Jakiej długości sznurka potrzebujesz? To pytanie jest nieokreślone, ponieważ zależy od użytych znaków. Ale co ważniejsze, jest to mylące. Potrzebujesz specyfikacji entropii łańcuchów, a nie ich długości. Entropia może być bezpośrednio związana z prawdopodobieństwem powtórzenia w pewnej liczbie ciągów. Długość łańcucha nie może.
I tu może pomóc biblioteka taka jak EntropyString . Aby wygenerować losowe identyfikatory, które mają mniej niż 1, z bilionem szansy na powtórzenie w 5 milionach ciągów przy użyciu
EntropyString
:EntropyString
używa domyślnie zestawu znaków zawierającego 32 znaki. Istnieją inne predefiniowane zestawy znaków, a także możesz określić własne znaki. Na przykład generowanie identyfikatorów z taką samą entropią jak powyżej, ale przy użyciu znaków szesnastkowych:Zwróć uwagę na różnicę długości łańcucha wynikającą z różnicy w całkowitej liczbie znaków w użytym zestawie znaków. Ryzyko powtórzenia w określonej liczbie potencjalnych ciągów jest takie samo. Długości łańcucha nie są. A co najważniejsze, ryzyko powtórzenia i potencjalna liczba ciągów jest wyraźna. Nigdy więcej zgadywania przy długości łańcucha.
źródło
Jeśli ciąg losowy powinien być bezpieczny-losowy, użyj tego:
źródło
Jeśli potrzebujesz tylko unikalnego identyfikatora,
UUID().uuidString
może służyć Twoim celom.źródło
Zaktualizowano dla Swift 4. Użyj leniwej zmiennej przechowywanej w rozszerzeniu klasy. Oblicza się to tylko raz.
źródło
SWIFT 4
Korzystanie z RandomNumberGenerator dla lepszej wydajności jako rekomendacji Apple
Zastosowanie:
String.random(20)
Wynik:CifkNZ9wy9jBOT0KJtV4
źródło
To Swift -est rozwiązanie mogłem wymyślić. Swift 3.0
źródło
źródło