Genera una stringa alfanumerica casuale in Cocoa

Voglio chiamare un metodo, passarlo di lunghezza e farlo generare una stringa alfanumerica casuale.

Ci sono delle librerie di utilità là fuori che possono avere un sacco di questi tipi di funzioni?

Ecco un’implementazione rapida e sporca. Non è stato testato

NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; -(NSString *) randomStringWithLength: (int) len { NSMutableString *randomString = [NSMutableString stringWithCapacity: len]; for (int i=0; i 

Non esattamente quello che chiedi, ma comunque utile:

 [[NSProcessInfo processInfo] globallyUniqueString] 

Uscita di esempio:

 450FEA63-2286-4B49-8ACC-9822C7D4356B-1376-00000239A4AC4FD5 
 NSString *alphabet = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXZY0123456789"; NSMutableString *s = [NSMutableString stringWithCapacity:20]; for (NSUInteger i = 0U; i < 20; i++) { u_int32_t r = arc4random() % [alphabet length]; unichar c = [alphabet characterAtIndex:r]; [s appendFormat:@"%C", c]; } 

Sicuramente puoi renderlo più breve:

 +(NSString*)generateRandomString:(int)num { NSMutableString* string = [NSMutableString stringWithCapacity:num]; for (int i = 0; i < num; i++) { [string appendFormat:@"%C", (unichar)('a' + arc4random_uniform(26))]; } return string; } 

Una versione di categoria della risposta di Jeff B.

NSString + Random.h

 #import  @interface NSString (Random) + (NSString *)randomAlphanumericStringWithLength:(NSInteger)length; @end 

NSString + Random.m

 #import "NSString+Random.h" @implementation NSString (Random) + (NSString *)randomAlphanumericStringWithLength:(NSInteger)length { NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; NSMutableString *randomString = [NSMutableString stringWithCapacity:length]; for (int i = 0; i < length; i++) { [randomString appendFormat:@"%C", [letters characterAtIndex:arc4random() % [letters length]]]; } return randomString; } @end 

Se sei disposto a limitarti solo a caratteri esadecimali, l’opzione più semplice è generare un UUID:

 NSString *uuid = [NSUUID UUID].UUIDString; 

Esempio di output: 16E3DF0B-87B3-4162-A1A1-E03DB2F59654 .

Se vuoi una stringa casuale più piccola, puoi afferrare solo i primi 8 caratteri.

È un UUID versione 4 che significa che il primo carattere nel 3 ° e 4 ° gruppo non è casuale (saranno sempre 4 e uno di 8 , 9 , A o B ).

Ogni altro carattere nella stringa è completamente casuale e puoi generare milioni di UUID al secondo per centinaia di anni senza il rischio che lo stesso UUID venga generato due volte.

Potresti anche solo generare un UUID. Sebbene non siano realmente casuali, sono complessi e unici, il che li rende casuali per la maggior parte degli usi. Genera uno come una stringa e poi prendi un intervallo di caratteri uguale alla lunghezza passata.

Ecco un modo diverso per affrontarlo. Invece di utilizzare una stringa di caratteri preparati, è ansible eseguire il cast tra numeri interi e caratteri e generare un elenco dinamico di caratteri da selezionare. È piuttosto snello e veloce, ma ha un po ‘più di codice.

 int charNumStart = (int) '0'; int charNumEnd = (int) '9'; int charCapitalStart = (int) 'A'; int charCapitalEnd = (int) 'Z'; int charLowerStart = (int) 'a'; int charLowerEnd = (int) 'z'; int amountOfChars = (charNumEnd - charNumStart) + (charCapitalEnd - charCapitalStart) + (charLowerEnd - charLowerStart); // amount of the characters we want. int firstGap = charCapitalStart - charNumEnd; // there are gaps of random characters between numbers and uppercase letters, so this allows us to skip those. int secondGap = charLowerStart - charCapitalEnd; // similar to above, but between uppercase and lowercase letters. // START generates a log to show us which characters we are considering for our UID. NSMutableString *chars = [NSMutableString stringWithCapacity:amountOfChars]; for (int i = charNumStart; i <= charLowerEnd; i++) { if ((i >= charNumStart && i <= charNumEnd) || (i >= charCapitalStart && i <= charCapitalEnd) || (i >= charLowerStart && i <= charLowerEnd)) { [chars appendFormat:@"\n%c", (char) i]; } } NSLog(@"chars: %@", chars); // END log // Generate a uid of 20 characters that chooses from our desired range. int uidLength = 20; NSMutableString *uid = [NSMutableString stringWithCapacity:uidLength]; for (int i = 0; i < uidLength; i++) { // Generate a random number within our character range. int randomNum = arc4random() % amountOfChars; // Add the lowest value number to line this up with a desirable character. randomNum += charNumStart; // if the number is in the letter range, skip over the characters between the numbers and letters. if (randomNum > charNumEnd) { randomNum += firstGap; } // if the number is in the lowercase letter range, skip over the characters between the uppercase and lowercase letters. if (randomNum > charCapitalEnd) { randomNum += secondGap; } // append the chosen character. [uid appendFormat:@"%c", (char) randomNum]; } NSLog(@"uid: %@", uid); // Generate a UID that selects any kind of character, including a lot of punctuation. It's a bit easier to do it this way. int amountOfAnyCharacters = charLowerEnd - charNumStart; // A new range of characters. NSMutableString *multiCharUid = [NSMutableString stringWithCapacity:uidLength]; for (int i = 0; i < uidLength; i++) { // Generate a random number within our new character range. int randomNum = arc4random() % amountOfAnyCharacters; // Add the lowest value number to line this up with our range of characters. randomNum += charNumStart; // append the chosen character. [multiCharUid appendFormat:@"%c", (char) randomNum]; } NSLog(@"multiCharUid: %@", multiCharUid); 

Quando eseguo la generazione casuale di caratteri, preferisco lavorare direttamente con i numeri interi e lanciarli, invece di scrivere la lista di caratteri da cui voglio attingere. Dichiarare le variabili nella parte superiore rende più indipendente il sistema, ma questo codice presuppone che i numeri avranno un valore inferiore rispetto alle lettere e che le lettere maiuscole avranno un valore inferiore rispetto alle lettere minuscole.

veloce

 func randomStringWithLength(length: Int) -> String { let alphabet = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" let upperBound = UInt32(count(alphabet)) return String((0.. Character in return alphabet[advance(alphabet.startIndex, Int(arc4random_uniform(upperBound)))] }) } 

Soluzione alternativa in Swift

 func generateString(len: Int) -> String { let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" let lettersLength = UInt32(countElements(letters)) let result = (0.. String in let idx = Int(arc4random_uniform(lettersLength)) return String(letters[advance(letters.startIndex, idx)]) } return "".join(result) } 

Aggiungendo alla buona risposta data da Melvin, ecco una funzione che ho fatto ( in SWIFT! ) Per ottenere una stringa casuale:

 func randomStringOfLength(length:Int)->String{ var wantedCharacters:NSString="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXZY0123456789" var s=NSMutableString(capacity: length) for (var i:Int = 0; i < length; i++) { let r:UInt32 = arc4random() % UInt32( wantedCharacters.length) let c:UniChar = wantedCharacters.characterAtIndex( Int(r) ) s.appendFormat("%C", c) } return s } 

Ecco un risultato del test dal chiamare randomStringOfLength(10) : uXa0igA8wm

Genera una stringa casuale alfanumerica minuscola con una lunghezza determinata:

 -(NSString*)randomStringWithLength:(NSUInteger)length { NSMutableString* random = [NSMutableString stringWithCapacity:length]; for (NSUInteger i=0; i '9') c += ('a'-'9'-1); [random appendFormat:@"%c", c]; } return random; } 

Se si desidera una stringa unicode casuale, è ansible creare byte casuali e quindi utilizzare quelli validi.

  OSStatus sanityCheck = noErr; uint8_t * randomBytes = NULL; size_t length = 200; // can of course be variable randomBytes = malloc( length * sizeof(uint8_t) ); memset((void *)randomBytes, 0x0, length); sanityCheck = SecRandomCopyBytes(kSecRandomDefault, length, randomBytes); if (sanityCheck != noErr) NSLog(@"Error generating random bytes, OSStatus == %ld.", sanityCheck); NSData* randomData = [[NSData alloc] initWithBytes:(const void *)randomBytes length: length]; if (randomBytes) free(randomBytes); NSString* dataString = [[NSString alloc] initWithCharacters:[randomData bytes] length:[randomData length]]; // create an NSString from the random bytes NSData* tempData = [dataString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; // remove illegal characters from string NSString* randomString = [[NSString alloc] initWithData:tempData encoding:NSUTF8StringEncoding]; 

La conversione da NSString a NSData e viceversa è necessaria per ottenere una stringa UTF-8 valida. Tieni presente che la lunghezza non sarà necessariamente la lunghezza della NSString creata alla fine.

L’ho fatto usando un semplice char[] invece di un NSString * per l’alfabeto. Ho aggiunto questo a una categoria NSString.

 static const char __alphabet[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; + (NSString *)randomString:(int)length { NSMutableString *randomString = [NSMutableString stringWithCapacity:length]; u_int32_t alphabetLength = (u_int32_t)strlen(__alphabet); for (int i = 0; i < length; i++) { [randomString appendFormat:@"%c", __alphabet[arc4random_uniform(alphabetLength)]]; } return randomString; } 
 static NSUInteger length = 32; static NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; NSMutableString * randomString = [NSMutableString stringWithCapacity:length]; for (NSInteger i = 0; i < length; ++i) { [randomString appendFormat: @"%C", [letters characterAtIndex:(NSUInteger)arc4random_uniform((u_int32_t)[letters length])]]; } 

Metodo per chiamare:


 NSString *string = [self stringWithRandomSuffixForFile:@"file.pdf" withLength:4] 

Metodo:


 - (NSString *)stringWithRandomSuffixForFile:(NSString *)file withLength:(int)length { NSString *alphabet = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; NSString *fileExtension = [file pathExtension]; NSString *fileName = [file stringByDeletingPathExtension]; NSMutableString *randomString = [NSMutableString stringWithFormat:@"%@_", fileName]; for (int x = 0; x < length; x++) { [randomString appendFormat:@"%C", [alphabet characterAtIndex: arc4random_uniform((int)[alphabet length]) % [alphabet length]]]; } [randomString appendFormat:@".%@", fileExtension]; NSLog(@"## randomString: %@ ##", randomString); return randomString; } 

risultati:


 ## randomString: file_Msci.pdf ## ## randomString: file_xshG.pdf ## ## randomString: file_abAD.pdf ## ## randomString: file_HVwV.pdf ## 

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

Modifica di alcune idee qui, e in fatto di Swift 4.0

 extension String { subscript (i: Int) -> Character { return self[index(startIndex, offsetBy:i)] } static func Random(length:Int=32, alphabet:String="ABCDEF0123456789") -> String { let upperBound = UInt32(alphabet.count) return String((0.. Character in return alphabet[Int(arc4random_uniform(upperBound))] }) } } 

Uso:

 let myHexString = String.Random() let myLongHexString = String.Random(length:64) let myLettersString = String.Random(length:32, alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
 #define ASCII_START_NUMERS 0x30 #define ASCII_END_NUMERS 0x39 #define ASCII_START_LETTERS_A 0x41 #define ASCII_END_LETTERS_Z 0x5A #define ASCII_START_LETTERS_a 0x61 #define ASCII_END_LETTERS_z 0x5A -(NSString *)getRandomString:(int)length { NSMutableString *result = [[NSMutableString alloc]init]; while (result.length != length) { NSMutableData* data = [NSMutableData dataWithLength:1]; SecRandomCopyBytes(kSecRandomDefault, 1, [data mutableBytes]); Byte currentChar = 0; [data getBytes:&currentChar length:1]; NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if (currentChar > ASCII_START_NUMERS && currentChar < ASCII_END_NUMERS) { // 0 to 0 [result appendString:s]; continue; } if (currentChar > ASCII_START_LETTERS_A && currentChar < ASCII_END_LETTERS_Z) { // 0 to 0 [result appendString:s]; continue; } if (currentChar > ASCII_START_LETTERS_a && currentChar < ASCII_END_LETTERS_z) { // 0 to 0 [result appendString:s]; continue; } } return result; } 

Modifica per la risposta di keithyip:

 + (NSString *)randomAlphanumericStringWithLength:(NSInteger)length { static NSString * const letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ srand(time(NULL)); }); NSMutableString *randomString = [NSMutableString stringWithCapacity:length]; for (int i = 0; i < length; i++) { [randomString appendFormat:@"%C", [letters characterAtIndex:arc4random() % [letters length]]]; } return randomString; }