답변:
빠르고 더러운 구현이 있습니다. 테스트되지 않았습니다.
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;
}
NSString
for 를 사용할 이유가 없습니다 . 실제로, 사용하는 것이 나보다 간결하지 않은 것 같습니다 . Foundation 수업은 실제로 도움이되지만 가장 간단한 것은 코드를 향상시키는 대신 모호하게 만드는 것입니다. letters
char
[letters characterAtIndex:(rand() % [letters length])]
letters[rand() % strlen(letters)]
%C
%c
characterAtIndex:
unichar
arc4random_uniform((int)[letters length])
정확히 당신이 묻는 것은 아니지만 여전히 유용합니다.
[[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];
}
alphabet
매번 길이를 쿼리해야 합니까? 일정하며 루프에 의존하지 않습니다.
NSArray
캐시는 length
성능 병목 현상이되어서는 안됩니다.
분명히 이것을 더 짧게 만들 수 있습니다.
+(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;
}
16 진수 문자로만 자신을 제한하려는 경우 가장 간단한 옵션은 UUID를 생성하는 것입니다.
NSString *uuid = [NSUUID UUID].UUIDString;
출력 예 : 16E3DF0B-87B3-4162-A1A1-E03DB2F59654
.
더 작은 임의의 문자열을 원하면 처음 8 자만 잡을 수 있습니다.
버전 4 UUID는 3 번째 및 4 번째 그룹의 첫 번째 문자가 무작위가 아님을 의미합니다 (항상 , 또는 , 4
중 하나임 ).8
9
A
B
문자열의 다른 모든 문자는 완전히 임의적이며 동일한 UUID가 두 번 생성 될 위험없이 수백 년 동안 매초마다 수백만 개의 UUID를 생성 할 수 있습니다.
NSString *uuid = [UUID UUID]
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
빠른
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)))]
})
}
64
된을 계산 된 것으로 교체했습니다 upperBound
. 나는 upperBound
그것이 더 나은 것으로 생각하기 때문에 블록 외부에서 계산 합니다.
이를 해결하는 다른 방법이 있습니다. 준비된 문자열을 사용하는 대신 정수와 문자를 캐스트하고 선택할 동적 문자 목록을 생성 할 수 있습니다. 꽤 간결하고 빠르지 만 조금 더 코드가 있습니다.
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);
임의의 문자 생성을 수행 할 때 정수를 사용하여 직접 작성하고 캐스트하는 대신 문자를 캐스트하는 것을 선호합니다. 상단에 변수를 선언하면 시스템 독립적이되지만이 코드는 숫자가 문자보다 값이 낮고 대문자가 소문자보다 값이 작다고 가정합니다.
스위프트의 대체 솔루션
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)
}
Melvin이 제공 한 좋은 대답에 추가하여 임의의 문자열을 얻기 위해 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;
}
몇 가지 아이디어를 수정하고 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];
유효한 UTF-8 문자열을 얻으려면 NSString에서 NSData로 또는 그 반대로 변환해야합니다. 길이는 반드시 끝에 생성 된 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 ##
스위프트 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;
}