Câu trả lời:
Cập nhật Swift 4.2
Swift 4.2 đã giới thiệu những cải tiến lớn trong việc xử lý các giá trị và các yếu tố ngẫu nhiên. Bạn có thể đọc thêm về những cải tiến ở đây . Đây là phương pháp rút gọn thành một vài dòng:
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
Cập nhật 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
}
Câu trả lời gốc:
func randomStringWithLength (len : Int) -> NSString {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString : NSMutableString = NSMutableString(capacity: len)
for (var i=0; i < len; i++){
var length = UInt32 (letters.length)
var rand = arc4random_uniform(length)
randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}
return randomString
}
Đây là một giải pháp sẵn sàng sử dụng theo cú pháp Swiftier . Bạn chỉ có thể sao chép và dán nó:
func randomAlphaNumericString(length: Int) -> String {
let allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let allowedCharsCount = UInt32(allowedChars.characters.count)
var randomString = ""
for _ in 0..<length {
let randomNum = Int(arc4random_uniform(allowedCharsCount))
let randomIndex = allowedChars.index(allowedChars.startIndex, offsetBy: randomNum)
let newCharacter = allowedChars[randomIndex]
randomString += String(newCharacter)
}
return randomString
}
Nếu bạn thích một Framework cũng có một số tính năng tiện dụng hơn thì hãy kiểm tra dự án của tôi HandySwift . Nó cũng bao gồm một giải pháp đẹp cho các chuỗi chữ và số ngẫu nhiên :
String(randomWithLength: 8, allowedCharactersType: .alphaNumeric) // => "2TgM5sUG"
Bạn cũng có thể sử dụng nó theo cách sau:
extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.characters.count))
randomString += "\(base[base.startIndex.advancedBy(Int(randomValue))])"
}
return randomString
}
}
Cách sử dụng đơn giản:
let randomString = String.random()
Cú pháp 3 Swift:
extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.characters.count))
randomString += "\(base[base.index(base.startIndex, offsetBy: Int(randomValue))])"
}
return randomString
}
}
Cú pháp Swift 4:
extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.count))
randomString += "\(base[base.index(base.startIndex, offsetBy: Int(randomValue))])"
}
return randomString
}
}
Nhanh:
let randomString = NSUUID().uuidString
Trong trường hợp bất thường đó
Đây là một chức năng cực kỳ rõ ràng mà lưu trữ :
func randomNameString(length: Int = 7)->String{
enum s {
static let c = Array("abcdefghjklmnpqrstuvwxyz12345789")
static let k = UInt32(c.count)
}
var result = [Character](repeating: "-", count: length)
for i in 0..<length {
let r = Int(arc4random_uniform(s.k))
result[i] = s.c[r]
}
return String(result)
}
Điều này là khi bạn có một bộ ký tự cố định, đã biết .
Mẹo tiện dụng:
Không có 0, o, O, i, v.v ... các nhân vật con người thường nhầm lẫn.
Điều này thường được thực hiện để đặt mã và các mã tương tự mà khách hàng của con người sẽ sử dụng.
repeating:count:
.
Đơn giản và nhanh chóng - UUID (). UuidString
// Trả về một chuỗi được tạo từ UUID, chẳng hạn như "E621E1F8-C36C-495A-93FC-0C247A3E6E5F"
công khai var uuidString: Chuỗi {get}
Swift 3.0
let randomString = UUID().uuidString //0548CD07-7E2B-412B-AD69-5B2364644433
print(randomString.replacingOccurrences(of: "-", with: ""))
//0548CD077E2B412BAD695B2364644433
BIÊN TẬP
Xin đừng nhầm lẫn với UIDevice.current.identifierForVendor?.uuidString
nó sẽ không cung cấp giá trị ngẫu nhiên.
Với Swift 4.2, cách tốt nhất của bạn là tạo một chuỗi với các ký tự bạn muốn và sau đó sử dụng RandomEuity để chọn từng ký tự:
let length = 32
let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomCharacters = (0..<length).map{_ in characters.randomElement()!}
let randomString = String(randomCharacters)
Tôi chi tiết hơn về những thay đổi ở đây .
Phiên bản Swift 2.2
// based on https://gist.github.com/samuel-mellert/20b3c99dec168255a046
// which is based on https://gist.github.com/szhernovoy/276e69eb90a0de84dd90
// Updated to work on Swift 2.2
func randomString(length: Int) -> String {
let charactersString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let charactersArray : [Character] = Array(charactersString.characters)
var string = ""
for _ in 0..<length {
string.append(charactersArray[Int(arc4random()) % charactersArray.count])
}
return string
}
Về cơ bản gọi phương thức này sẽ tạo ra một chuỗi ngẫu nhiên độ dài của số nguyên được trao cho hàm. Để thay đổi các ký tự có thể, chỉ cần chỉnh sửa chuỗi characterString. Hỗ trợ các ký tự unicode quá.
https://gist.github.com/gingofthesouth/54bea667b28a815b2fe33a4da986e327
EXC_BAD_INSTRUCTION
let random = randomString(16)
. EXC chỉ có trên một thiết bị thực và tôi đã không nhìn thấy nó trong một trình giả lập và nó không liên tục trên thiết bị.
random % count
không không (luôn luôn) tạo ra một phân bố đều. Nếu điều này có liên quan đến bạn, hãy tìm đến những câu trả lời khác sử dụng arc4random_uniform()
.
Dành cho những người không muốn gõ toàn bộ bộ ký tự:
func randomAlphanumericString(length: Int) -> String {
enum Statics {
static let scalars = [UnicodeScalar("a").value...UnicodeScalar("z").value,
UnicodeScalar("A").value...UnicodeScalar("Z").value,
UnicodeScalar("0").value...UnicodeScalar("9").value].joined()
static let characters = scalars.map { Character(UnicodeScalar($0)!) }
}
let result = (0..<length).map { _ in Statics.characters.randomElement()! }
return String(result)
}
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
}
Một Swift ngẫu nhiên thuần túy String
từ bất kỳ CharacterSet
.
Sử dụng: CharacterSet.alphanumerics.randomString(length: 100)
extension CharacterSet {
/// extracting characters
/// https://stackoverflow.com/a/52133647/1033581
public func characters() -> [Character] {
return codePoints().compactMap { UnicodeScalar($0) }.map { Character($0) }
}
public func codePoints() -> [Int] {
var result: [Int] = []
var plane = 0
for (i, w) in bitmapRepresentation.enumerated() {
let k = i % 8193
if k == 8192 {
plane = Int(w) << 13
continue
}
let base = (plane + k) << 3
for j in 0 ..< 8 where w & 1 << j != 0 {
result.append(base + j)
}
}
return result
}
/// building random string of desired length
/// https://stackoverflow.com/a/42895178/1033581
public func randomString(length: Int) -> String {
let charArray = characters()
let charArrayCount = UInt32(charArray.count)
var randomString = ""
for _ in 0 ..< length {
randomString += String(charArray[Int(arc4random_uniform(charArrayCount))])
}
return randomString
}
}
Các characters()
chức năng là thực hiện được biết đến nhanh nhất của tôi .
func randomString(length: Int) -> String {
// whatever letters you want to possibly appear in the output (unicode handled properly by Swift)
let letters = "abcABC012你好吗😀🐱💥∆𝚹∌⌘"
let n = UInt32(letters.characters.count)
var out = ""
for _ in 0..<length {
let index = letters.startIndex.advancedBy(Int(arc4random_uniform(n)))
out.append(letters[index])
}
return out
}
Việc thực hiện Swift-ier thậm chí nhiều hơn của tôi về câu hỏi:
func randomAlphanumericString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".characters
let lettersLength = UInt32(letters.count)
let randomCharacters = (0..<length).map { i -> String in
let offset = Int(arc4random_uniform(lettersLength))
let c = letters[letters.startIndex.advancedBy(offset)]
return String(c)
}
return randomCharacters.joinWithSeparator("")
}
Vòng lặp miễn phí, mặc dù nó được giới hạn trong 43 ký tự. Nếu bạn cần nhiều hơn, nó có thể được sửa đổi. Cách tiếp cận này có hai ưu điểm so với chỉ sử dụng UUID:
UUID()
chỉ tạo chữ cái viết hoaUUID
dài tối đa 36 ký tự (bao gồm 4 dấu gạch nối), nhưng chỉ dài 32 ký tự mà không có. Nếu bạn cần một cái gì đó lâu hơn, hoặc không muốn có dấu gạch nối, việc sử dụng base64EncodedString
tay cầm nàyNgoài ra, hàm này sử dụng a UInt
để tránh các số âm.
func generateRandom(size: UInt) -> String {
let prefixSize = Int(min(size, 43))
let uuidString = UUID().uuidString.replacingOccurrences(of: "-", with: "")
return String(Data(uuidString.utf8)
.base64EncodedString()
.replacingOccurrences(of: "=", with: "")
.prefix(prefixSize))
}
Gọi nó trong một vòng lặp để kiểm tra đầu ra:
for _ in 0...10 {
print(generateRandom(size: 32))
}
Sản xuất:
Nzk3NjgzMTdBQ0FBNDFCNzk2MDRENzZF
MUI5RURDQzE1RTdCNDA3RDg2MTI4QkQx
M0I3MjJBRjVFRTYyNDFCNkI5OUM1RUVC
RDA1RDZGQ0IzQjI1NDdGREI3NDgxM0Mx
NjcyNUQyOThCNzhCNEVFQTk1RTQ3NTIy
MDkwRTQ0RjFENUFGNEFDOTgyQTUxODI0
RDU2OTNBOUJGMDE4NDhEODlCNEQ1NjZG
RjM2MTUxRjM4RkY3NDU2OUFDOTI0Nzkz
QzUwOTE1N0U1RDVENDE4OEE5NTM2Rjcy
Nzk4QkMxNUJEMjYwNDJDQjhBQkY5QkY5
ODhFNjU0MDVEMUI2NEI5QUIyNjNCNkVF
Swift 5.0
// Generating Random String
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
// Calling to string
label.text = randomString(length: 3)
Vấn đề với các câu trả lời cho câu hỏi "Tôi cần chuỗi ngẫu nhiên" (bằng bất kỳ ngôn ngữ nào) thực tế là mọi giải pháp đều sử dụng một đặc tả chính thiếu sót về độ dài chuỗi . Các câu hỏi hiếm khi tiết lộ lý do tại sao các chuỗi ngẫu nhiên là cần thiết, nhưng tôi sẽ thách thức bạn hiếm khi cần các chuỗi có độ dài ngẫu nhiên, nói 8. Điều bạn luôn cần là một số chuỗi duy nhất , ví dụ, để sử dụng làm định danh cho mục đích nào đó.
Có hai cách hàng đầu để có được các chuỗi duy nhất nghiêm ngặt : xác định (không ngẫu nhiên) và lưu trữ / so sánh (đó là rất khó). Chúng ta làm gì? Chúng tôi từ bỏ con ma. Chúng tôi đi với sự độc đáo xác suất thay thế. Đó là, chúng tôi chấp nhận rằng có một số rủi ro (dù nhỏ) rằng chuỗi của chúng tôi sẽ không phải là duy nhất. Đây là nơi hiểu xác suất va chạm và entropy là hữu ích.
Vì vậy, tôi sẽ định nghĩa lại nhu cầu bất biến là cần một số chuỗi có rủi ro lặp lại nhỏ. Ví dụ cụ thể, giả sử bạn muốn tạo tiềm năng 5 triệu ID. Bạn không muốn lưu trữ và so sánh từng chuỗi mới và bạn muốn chúng là ngẫu nhiên, vì vậy bạn chấp nhận một số rủi ro lặp lại. Ví dụ: giả sử rủi ro ít hơn 1 trong một nghìn tỷ cơ hội lặp lại. Vậy bạn cần độ dài của chuỗi? Vâng, câu hỏi đó không được xác định rõ vì nó phụ thuộc vào các ký tự được sử dụng. Nhưng quan trọng hơn, đó là sai lầm. Những gì bạn cần là một đặc điểm kỹ thuật của entropy của chuỗi, không phải độ dài của chúng. Entropy có thể liên quan trực tiếp đến xác suất lặp lại trong một số chuỗi. Độ dài chuỗi không thể.
Và đây là nơi một thư viện như EntropyString có thể giúp đỡ. Để tạo ID ngẫu nhiên có ít hơn 1 trong một nghìn tỷ cơ hội lặp lại trong 5 triệu chuỗi bằng cách sử dụng EntropyString
:
import EntropyString
let random = Random()
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
"Rrrj6pN4d6GBrFLH4"
EntropyString
sử dụng một bộ ký tự với 32 ký tự theo mặc định. Có các bộ ký tự được xác định trước khác và bạn cũng có thể chỉ định các ký tự của riêng mình. Ví dụ: tạo ID có cùng entropy như trên nhưng sử dụng các ký tự hex:
import EntropyString
let random = Random(.charSet16)
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
"135fe71aec7a80c02dce5"
Lưu ý sự khác biệt về độ dài chuỗi do sự khác biệt về tổng số ký tự trong bộ ký tự được sử dụng. Nguy cơ lặp lại trong số lượng các chuỗi tiềm năng được chỉ định là như nhau. Độ dài chuỗi không. Và tốt nhất, nguy cơ lặp lại và số chuỗi tiềm năng là rõ ràng. Không còn phải đoán với độ dài chuỗi.
Nếu chuỗi ngẫu nhiên của bạn phải an toàn-ngẫu nhiên, hãy sử dụng:
import Foundation
import Security
// ...
private static func createAlphaNumericRandomString(length: Int) -> String? {
// create random numbers from 0 to 63
// use random numbers as index for accessing characters from the symbols string
// this limit is chosen because it is close to the number of possible symbols A-Z, a-z, 0-9
// so the error rate for invalid indices is low
let randomNumberModulo: UInt8 = 64
// indices greater than the length of the symbols string are invalid
// invalid indices are skipped
let symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
var alphaNumericRandomString = ""
let maximumIndex = symbols.count - 1
while alphaNumericRandomString.count != length {
let bytesCount = 1
var randomByte: UInt8 = 0
guard errSecSuccess == SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomByte) else {
return nil
}
let randomIndex = randomByte % randomNumberModulo
// check if index exceeds symbols string length, then skip
guard randomIndex <= maximumIndex else { continue }
let symbolIndex = symbols.index(symbols.startIndex, offsetBy: Int(randomIndex))
alphaNumericRandomString.append(symbols[symbolIndex])
}
return alphaNumericRandomString
}
Nếu bạn chỉ cần một định danh duy nhất, UUID().uuidString
có thể phục vụ mục đích của bạn.
Đã cập nhật cho Swift 4. Sử dụng biến được lưu trữ lười biếng trên phần mở rộng lớp. Điều này chỉ được tính một lần.
extension String {
static var chars: [Character] = {
return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".map({$0})
}()
static func random(length: Int) -> String {
var partial: [Character] = []
for _ in 0..<length {
let rand = Int(arc4random_uniform(UInt32(chars.count)))
partial.append(chars[rand])
}
return String(partial)
}
}
String.random(length: 10) //STQp9JQxoq
Chuyển 4
Sử dụng RandomNumberGenerator để có hiệu suất tốt hơn như khuyến nghị của Apple
Cách sử dụng: String.random(20)
Kết quả:CifkNZ9wy9jBOT0KJtV4
extension String{
static func random(length:Int)->String{
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString = ""
while randomString.utf8.count < length{
let randomLetter = letters.randomElement()
randomString += randomLetter?.description ?? ""
}
return randomString
}
}
Đây là Swift giải pháp -est tôi có thể đưa ra. Swift 3.0
extension String {
static func random(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomLength = UInt32(letters.characters.count)
let randomString: String = (0 ..< length).reduce(String()) { accum, _ in
let randomOffset = arc4random_uniform(randomLength)
let randomIndex = letters.index(letters.startIndex, offsetBy: Int(randomOffset))
return accum.appending(String(letters[randomIndex]))
}
return randomString
}
}
func randomUIDString(_ wlength: Int) -> String {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString = ""
for _ in 0 ..< wlength {
let length = UInt32 (letters.length)
let rand = arc4random_uniform(length)
randomString = randomString.appendingFormat("%C", letters.character(at: Int(rand)));
}
return randomString
}