Comment générer une chaîne alphanumérique aléatoire dans Swift?
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
Swift 4.2 a apporté d’importantes améliorations dans la gestion des valeurs et des éléments aléatoires. Vous pouvez en savoir plus sur ces améliorations ici . Voici la méthode réduite à quelques lignes:
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0...length-1).map{ _ in letters.randomElement()! })
}
Voici une solution prête à l'emploi dans la syntaxe Swiftier. Vous pouvez simplement copier et coller:
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
}
Si vous préférez un Framework qui possède également des fonctionnalités plus pratiques, n'hésitez pas à consulter mon projet HandySwift. Il comprend également une belle solution pour les chaînes alphanumériques aléatoires}:
String(randomWithLength: 8, allowedCharactersType: .alphaNumeric) // => "2TgM5sUG"
Vous pouvez également l'utiliser de la manière suivante:
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
}
}
Utilisation simple:
let randomString = String.random()
Syntaxe de 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
}
}
Syntaxe de 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
}
}
Rapide:
let randomString = NSUUID().uuidString
Avec Swift 4.2, votre meilleur choix est de créer une chaîne avec les caractères de votre choix, puis utilisez randomElement pour choisir chaque caractère:
let length = 32
let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomCharacters = (0..<length).map{_ in characters.randomElement()!}
let randomString = String(randomCharacters)
Je détaille plus sur ces changements ici .
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
}
Appelez fondamentalement cette méthode qui générera une chaîne aléatoire de la longueur de l'entier transmis à la fonction. Pour changer les caractères possibles, éditez simplement la chaîne charactersString. Prend en charge les caractères unicode aussi.
https://Gist.github.com/gingofthesouth/54bea667b28a815b2fe33a4da986e327
Simple et rapide - UUID (). UuidString
// renvoie une chaîne créée à partir de l'UUID, telle que "E621E1F8-C36C-495A-93FC-0C247A3E6E5F"
public var uuidString: String {get}
Swift 3.0
let randomString = UUID().uuidString //0548CD07-7E2B-412B-AD69-5B2364644433
print(randomString.replacingOccurrences(of: "-", with: ""))
//0548CD077E2B412BAD695B2364644433
MODIFIER
Veuillez ne pas confondre avec UIDevice.current.identifierForVendor?.uuidString
, il ne donnera pas de valeurs aléatoires.
pour 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
}
Peut sauver quelqu'un en tapant, si vous avez le cas inhabituel qui
Voici une fonction extrêmement simple, claire et autonome qui met en cache,
(Je pense que c'est le genre de choses que vous laisseriez à la portée mondiale pour plus de simplicité.)
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)
}
Notez que le point ici est qu'il s'agit d'un jeu de caractères fixe et connu - il est mis en cache.
Si vous avez besoin d'un autre jeu de caractères différent, créez une autre fonction en cache,
func randomVowelsString(length: Int = 20)->String{
enum s {
static let c = Array("AEIOU".characters)
...
Astuce pratique:
Il n'y a pas de 0, o, O, i, etc ... les personnages que les humains confondent souvent.
Ceci est souvent fait pour les codes de réservation, etc.
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
}
Ma encore plus rapide mise en oeuvre de la question:
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("")
}
Si votre chaîne aléatoire doit être sécurisée-aléatoire, utilisez ceci:
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
}
Un pur Swift aléatoire String
de toute CharacterSet
.
Usage: 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
}
}
La fonction characters()
est mon implémentation la plus rapide connue .
Boucle libre, mais limité à 43 caractères. Si vous avez besoin de plus, il peut être modifié. Cette approche présente deux avantages par rapport à l’utilisation exclusive d’un UUID:
UUID()
ne génère que des majusculesUUID
comporte au plus 36 caractères (y compris les 4 tirets), mais seulement 32 caractères sans. Si vous avez besoin de quelque chose de plus, ou si vous ne voulez pas que des tirets soient inclus, l’utilisation du base64EncodedString
gère cetteDe plus, cette fonction utilise une UInt
pour éviter les nombres négatifs.
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))
}
L'appeler en boucle pour vérifier la sortie:
for _ in 0...10 {
print(generateRandom(size: 32))
}
Qui produit:
Nzk3NjgzMTdBQ0FBNDFCNzk2MDRENzZF
MUI5RURDQzE1RTdCNDA3RDg2MTI4QkQx
M0I3MjJBRjVFRTYyNDFCNkI5OUM1RUVC
RDA1RDZGQ0IzQjI1NDdGREI3NDgxM0Mx
NjcyNUQyOThCNzhCNEVFQTk1RTQ3NTIy
MDkwRTQ0RjFENUFGNEFDOTgyQTUxODI0
RDU2OTNBOUJGMDE4NDhEODlCNEQ1NjZG
RjM2MTUxRjM4RkY3NDU2OUFDOTI0Nzkz
QzUwOTE1N0U1RDVENDE4OEE5NTM2Rjcy
Nzk4QkMxNUJEMjYwNDJDQjhBQkY5QkY5
ODhFNjU0MDVEMUI2NEI5QUIyNjNCNkVF
Mis à jour pour Swift 4. Utilisez une variable stockée paresseuse sur l'extension de classe. Ceci n'est calculé qu'une fois.
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
C’est la solution Swift -est que je pourrais trouver. 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
}
}
Swift 4
Utilisation de RandomNumberGenerator pour obtenir de meilleures performances que la recommandation Apple
Utilisation: String.random(20)
Résultat: 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
}
}
Si vous avez juste besoin d'un identifiant unique, UUID().uuidString
peut vous aider.
Pour les personnes qui ne veulent pas taper tout le jeu de caractères:
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)
}