Câu trả lời:
Đây là một thực hiện nhanh chóng và bẩn. Chưa được thử nghiệm.
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
để letters
khi một đơn giản char
mảng sẽ chỉ làm việc tốt. Trong thực tế, việc sử dụng [letters characterAtIndex:(rand() % [letters length])]
dường như đối với tôi là ít súc tích hơn chỉ letters[rand() % strlen(letters)]
. Các lớp Foundation thực sự hữu ích, nhưng đối với những điều đơn giản nhất, chúng có thể phục vụ để làm xáo trộn mã của chúng tôi hơn là tăng cường nó.
%C
thay vì %c
, vì characterAtIndex:
trả về mộtunichar
arc4random_uniform((int)[letters length])
Không chính xác những gì bạn yêu cầu, nhưng vẫn hữu ích:
[[NSProcessInfo processInfo] globallyUniqueString]
Đầu ra mẫu:
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
mỗi lần? Nó là hằng số và không phụ thuộc vào vòng lặp.
NSArray
lưu trữ nó length
, không nên là một nút cổ chai hiệu suất.
Chắc chắn bạn có thể làm điều này ngắn hơn:
+(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;
}
Nếu bạn sẵn sàng giới hạn bản thân chỉ ở các ký tự hex, thì tùy chọn đơn giản nhất là tạo UUID:
NSString *uuid = [NSUUID UUID].UUIDString;
Ví dụ đầu ra : 16E3DF0B-87B3-4162-A1A1-E03DB2F59654
.
Nếu bạn muốn một chuỗi ngẫu nhiên nhỏ hơn thì bạn chỉ có thể lấy 8 ký tự đầu tiên.
Đó là một UUID phiên bản 4 có nghĩa là nhân vật đầu tiên trong 3 và 4 nhóm không phải là ngẫu nhiên (họ sẽ luôn luôn được 4
và một trong những 8
, 9
, A
hoặc B
).
Mỗi ký tự khác trong chuỗi là hoàn toàn ngẫu nhiên và bạn có thể tạo ra hàng triệu UUID mỗi giây trong hàng trăm năm mà không có nhiều rủi ro về cùng một UUID được tạo hai lần.
NSString *uuid = [UUID UUID]
Một phiên bản thể loại của câu trả lời của Jeff B.
NSString + Ngẫu nhiên.h
#import <Foundation/Foundation.h>
@interface NSString (Random)
+ (NSString *)randomAlphanumericStringWithLength:(NSInteger)length;
@end
NSString + Ngẫu nhiên
#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
Bạn cũng có thể tạo UUID. Mặc dù không thực sự ngẫu nhiên, chúng rất phức tạp và độc đáo khiến chúng có vẻ ngẫu nhiên cho hầu hết các mục đích sử dụng. Tạo một chuỗi dưới dạng một chuỗi và sau đó lấy một phạm vi các ký tự bằng với độ dài được truyền.
Nhanh
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
bằng một máy tính upperBound
. Tôi tính toán upperBound
bên ngoài khối vì tôi nghĩ rằng nó hoạt động tốt hơn.
Đây là một cách khác nhau để giải quyết nó. Thay vì sử dụng một chuỗi ký tự đã chuẩn bị, bạn có thể chuyển giữa các số nguyên và ký tự và tạo một danh sách các ký tự động để chọn. Nó khá gọn gàng và nhanh, nhưng có thêm một chút mã.
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);
Khi tôi thực hiện việc tạo nhân vật ngẫu nhiên, tôi thích làm việc trực tiếp với các số nguyên và bỏ qua chúng, thay vì viết ra danh sách các ký tự mà tôi muốn rút ra. Khai báo các biến ở trên cùng làm cho nó độc lập hơn với hệ thống, nhưng mã này giả định rằng các số sẽ có giá trị thấp hơn các chữ cái và các chữ cái viết hoa sẽ có giá trị thấp hơn các chữ cái viết thường.
Giải pháp thay thế trong 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)
}
Thêm vào câu trả lời hay được đưa ra bởi Melvin, đây là một hàm tôi đã thực hiện ( trong SWIFT! ) Để có được một chuỗi ngẫu nhiên:
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
}
Đây là kết quả kiểm tra từ cuộc gọi randomStringOfLength(10)
: uXa0igA8wm
Tạo chuỗi ngẫu nhiên chữ và số viết thường với độ dài cho trước:
-(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;
}
Sửa đổi một vài ý tưởng ở đây và thực hiện 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))]
})
}
}
Sử dụng:
let myHexString = String.Random()
let myLongHexString = String.Random(length:64)
let myLettersString = String.Random(length:32, alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Nếu bạn muốn một chuỗi unicode ngẫu nhiên, bạn có thể tạo các byte ngẫu nhiên và sau đó sử dụng các chuỗi hợp lệ.
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];
Việc chuyển đổi từ NSString sang NSData trở lại là cần thiết để có được chuỗi UTF-8 hợp lệ. Xin lưu ý rằng độ dài sẽ không nhất thiết là độ dài của NSString được tạo cuối cùng.
Tôi đã làm điều này bằng cách sử dụng một đơn giản char[]
thay vì một NSString *
bảng chữ cái. Tôi đã thêm nó vào danh mục 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])]];
}
Phương thức gọi:
NSString *string = [self stringWithRandomSuffixForFile:@"file.pdf" withLength:4]
Phương pháp:
- (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;
}
Các kết quả:
## randomString: file_Msci.pdf ##
## randomString: file_xshG.pdf ##
## randomString: file_abAD.pdf ##
## randomString: file_HVwV.pdf ##
cho 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;
}
Sửa đổi cho câu trả lời của 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;
}