Генерация случайной буквенно-цифровой строки в какао
Я хочу вызвать метод, передать ему длину и заставить его генерировать случайную буквенно-цифровую строку.
существуют ли какие-либо служебные библиотеки, которые могут иметь кучу этих типов функций?
20 ответов:
вот быстрая и грязная реализация. Не был проверен.
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; }
не совсем то, что вы просите, но все равно полезно:
[[NSProcessInfo processInfo] globallyUniqueString]
пример вывода:
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]; }
конечно, вы можете сделать это короче:
+(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; }
версия категории ответа Джеффа Б.
NSString + Random.h
#import <Foundation/Foundation.h> @interface NSString (Random) + (NSString *)randomAlphanumericStringWithLength:(NSInteger)length; @end
NSString + Random.м
#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
если вы хотите ограничить себя только шестнадцатеричными символами, то самый простой вариант-создать UUID:
NSString *uuid = [NSUUID UUID].UUIDString;
пример:
16E3DF0B-87B3-4162-A1A1-E03DB2F59654
.если вы хотите меньшую случайную строку, то вы можете захватить только первые 8 символов.
это версия 4 UUID, которая означает, что первый символ в 3-й и 4-й группе не является случайным (они всегда будут
4
и8
,9
,A
илиB
).все остальные символ в строке полностью случайный, и вы можете генерировать миллионы UUID каждую секунду в течение сотен лет без особого риска того, что один и тот же UUID будет генерироваться дважды.
вы также можете просто создать UUID. Хотя они не являются действительно случайными, они сложны и уникальны, что делает их случайными для большинства применений. Создайте его в виде строки, а затем возьмите диапазон символов, равный переданной длине.
вот другой способ решить эту проблему. Вместо использования заранее подготовленной строки символов можно выполнять приведение между целыми числами и символами и создавать динамический список символов для выбора. Это довольно худой и быстрый, но имеет немного больше кода.
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);
когда я делаю генерацию случайных символов, я предпочитаю работать непосредственно с целыми числами и отбрасывать их, вместо того, чтобы выписывать список символов, из которых я хочу рисовать. Объявление переменных в верхней части делает его более независимо от системы, но этот код предполагает, что числа будут иметь меньшее значение, чем буквы, и что прописные буквы будут иметь меньшее значение, чем строчные буквы.
Swift
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)))] }) }
альтернативное решение в 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) }
добавление к хорошему ответу, данному Мелвином, вот функция, которую я сделал (в SWIFT!), чтобы получить случайную строку:
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 }
вот результат теста от вызова
randomStringOfLength(10)
:uXa0igA8wm
генерирует строчную буквенно-цифровую случайную строку заданной длины:
-(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; }
модификация нескольких идей здесь, и в done 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..<length).map { _ -> Character in return alphabet[Int(arc4random_uniform(upperBound))] }) } }
использование:
let myHexString = String.Random() let myLongHexString = String.Random(length:64) let myLettersString = String.Random(length:32, alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Если вы хотите случайную строку Юникода, вы можете создать случайные байты, а затем использовать допустимые.
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];
преобразование из NSString в NSData и обратно необходимо для получения допустимой строки UTF-8. Имейте в виду, что длина не обязательно будет длиной строки NSString, созданной в конце.
Я сделал это с помощью простого
char[]
вместоNSString *
для алфавита. Я добавил Это в категорию 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])]]; }
метод для вызова:
NSString *string = [self stringWithRandomSuffixForFile:@"file.pdf" withLength:4]
способ:
- (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; }
результаты:
## randomString: file_Msci.pdf ## ## randomString: file_xshG.pdf ## ## randomString: file_abAD.pdf ## ## randomString: file_HVwV.pdf ##
для 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:¤tChar 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; }
модификация для ответа 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; }