Gere uma string alfanumérica aleatória em Cocoa

Eu quero chamar um método, passar o comprimento e gerar uma string alfanumérica aleatória.

Existem algumas bibliotecas de utilidades que podem ter vários tipos de funções?

Aqui está uma implementação rápida e suja. Não foi testado.

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

Não é exatamente o que você pergunta, mas ainda é útil:

 [[NSProcessInfo processInfo] globallyUniqueString] 

Exemplo de saída:

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

Certamente você pode fazer isso mais curto:

 +(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; } 

Uma versão de categoria da resposta de 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 você estiver disposto a se limitar apenas a caracteres hexadecimais, a opção mais simples é gerar um UUID:

 NSString *uuid = [NSUUID UUID].UUIDString; 

Exemplo de saída: 16E3DF0B-87B3-4162-A1A1-E03DB2F59654 .

Se você quiser uma string aleatória menor, você pode pegar apenas os 8 primeiros caracteres.

É uma versão 4 UUID que significa que o primeiro caractere no 3º e 4º grupo não é random (eles serão sempre 4 e um de 8 , 9 , A ou B ).

Todos os outros caracteres da string são totalmente randoms e você pode gerar milhões de UUIDs a cada segundo por centenas de anos sem muito risco de que o mesmo UUID seja gerado duas vezes.

Você também pode simplesmente gerar um UUID. Embora não sejam verdadeiramente randoms, eles são complexos e únicos, o que os faz parecer randoms para a maioria dos usos. Gere um como uma string e, em seguida, use um intervalo de caracteres igual ao tamanho passado.

Aqui está uma maneira diferente de lidar com isso. Em vez de usar uma sequência de caracteres preparada, você pode converter entre inteiros e caracteres e gerar uma lista dinâmica de caracteres para selecionar. É bem enxuto e rápido, mas tem um pouco mais de código.

 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 estou fazendo uma geração aleatória de caracteres, prefiro trabalhar diretamente com números inteiros e lançá-los, em vez de escrever a lista de caracteres que desejo extrair. Declarar as variables ​​no topo torna-o mais independente do sistema, mas este código assume que os números terão um valor menor que as letras e que as letras maiúsculas terão um valor menor que as minúsculas.

Rápido

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

Solução alternativa em 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) } 

Somando a boa resposta dada por Melvin, aqui está uma function que fiz ( em SWIFT! ) Para obter uma string aleatória:

 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 } 

Aqui está um resultado de teste de calling randomStringOfLength(10) : uXa0igA8wm

Gera cadeia aleatória alfanumérica em letras minúsculas com tamanho determinado:

 -(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 você quiser uma string unicode aleatória, você pode criar bytes randoms e, em seguida, usar os válidos.

  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]; 

A conversão de NSString para NSData e back é necessária para obter uma string UTF-8 válida. Esteja ciente de que o comprimento não será necessariamente o comprimento do NSString criado no final.

Eu fiz isso usando um char[] simples char[] vez de um NSString * para o alfabeto. Eu adicionei isso a uma 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])]]; } 

Método para chamar:


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

Método:


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

Resultados:


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

para o 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ção de algumas idéias aqui, e no feito 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ção para a resposta do 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; } 
    Intereting Posts