objective-c cocoa string random alphanumeric

objective c - Generar una cadena alfanumérica aleatoria en Cocoa



objective-c string (20)

Quiero llamar a un método, pasarlo por alto y hacer que genere una cadena alfanumérica aleatoria.

¿Hay alguna biblioteca de utilidad que pueda tener un montón de este tipo de funciones?


Agregando a la buena respuesta dada por Melvin, aquí hay una función que hice (¡ en SWIFT! ) Para obtener una cadena aleatoria:

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 }

Aquí hay un resultado de la prueba al llamar a randomStringOfLength(10) : uXa0igA8wm


Aquí hay una forma diferente de abordarlo. En lugar de utilizar una cadena de caracteres preparada, puede convertir entre enteros y caracteres, y generar una lista dinámica de caracteres para seleccionar. Es bastante delgado y rápido, pero tiene un poco más 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);

Cuando realizo la generación aleatoria de caracteres, prefiero trabajar directamente con números enteros y enviarlos, en lugar de escribir la lista de caracteres que quiero dibujar. Declarar las variables en la parte superior lo hace más independiente del sistema, pero este código asume que los números tendrán un valor menor que las letras, y que las letras mayúsculas tendrán un valor menor que las letras minúsculas.


Aquí hay una implementación rápida y sucia. No ha sido probado.

NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; -(NSString *) randomStringWithLength: (int) len { NSMutableString *randomString = [NSMutableString stringWithCapacity: len]; for (int i=0; i<len; i++) { [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random_uniform([letters length])]]; } return randomString; }


Genera cadenas aleatorias alfanuméricas en minúsculas con una longitud dada:

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


Hice esto usando un simple char[] lugar de un NSString * para el alfabeto. Agregué esto a una categoría 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; }


Modificación de algunas ideas aquí, y en Swift 4.0 hecho

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..<length).map { _ -> 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")


Modificación para la respuesta de 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; }


No es exactamente lo que preguntas, pero sigue siendo útil:

[[NSProcessInfo processInfo] globallyUniqueString]

Muestra de salida:

450FEA63-2286-4B49-8ACC-9822C7D4356B-1376-00000239A4AC4FD5


Rápido

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


Seguramente puedes hacer esto más corto:

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


Si desea una cadena Unicode aleatoria, puede crear bytes aleatorios y luego usar los 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];

La conversión de NSString a NSData y viceversa es necesaria para obtener una cadena UTF-8 válida. Tenga en cuenta que la longitud no necesariamente será la longitud del NSString creado al final.


Si está dispuesto a limitarse solo a caracteres hexadecimales, la opción más simple es generar un UUID:

NSString *uuid = [NSUUID UUID].UUIDString;

Ejemplo de salida: 16E3DF0B-87B3-4162-A1A1-E03DB2F59654 .

Si desea una cadena aleatoria más pequeña, puede obtener solo los primeros 8 caracteres.

Es un UUID de la versión 4, lo que significa que el primer personaje del 3er y 4to grupo no es aleatorio (siempre serán 4 y uno de 8 , 9 , A o B ).

Todos los demás caracteres de la cadena son totalmente aleatorios y puede generar millones de UUID por segundo durante cientos de años sin mucho riesgo de generar el mismo UUID dos veces.


Solución alternativa en Swift

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


También podría generar un UUID. Aunque no son verdaderamente aleatorios, son complejos y únicos, lo que los hace parecer aleatorios para la mayoría de los usos. Genere uno como una cadena y luego tome un rango de caracteres igual a la longitud pasada.


Una versión de categoría de la respuesta de Jeff B.

NSString + Random.h

#import <Foundation/Foundation.h> @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


Método para llamar:

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


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


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


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