Jawaban:
Swift 4.2 Update
Swift 4.2 memperkenalkan peningkatan besar dalam berurusan dengan nilai dan elemen acak. Anda dapat membaca lebih lanjut tentang peningkatan tersebut di sini . Berikut ini metode yang direduksi menjadi beberapa baris:
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
Pembaruan 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
}
Jawaban asli:
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
}
Inilah solusi yang siap digunakan dalam sintaks Swiftier . Anda cukup menyalin dan menempelkannya:
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
}
Jika Anda lebih suka Kerangka yang juga memiliki beberapa fitur yang lebih berguna maka jangan ragu untuk checkout proyek saya HandySwift . Ini juga termasuk solusi yang bagus untuk string alfanumerik acak :
String(randomWithLength: 8, allowedCharactersType: .alphaNumeric) // => "2TgM5sUG"
Anda dapat menggunakannya juga dengan cara berikut:
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
}
}
Penggunaan sederhana:
let randomString = String.random()
Sintaks Swift 3:
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
}
}
Sintaks 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
}
}
Cepat:
let randomString = NSUUID().uuidString
Dengan Swift 4.2, taruhan terbaik Anda adalah membuat string dengan karakter yang Anda inginkan dan kemudian menggunakan randomElement untuk memilih setiap karakter:
let length = 32
let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomCharacters = (0..<length).map{_ in characters.randomElement()!}
let randomString = String(randomCharacters)
Saya lebih detail tentang perubahan ini di sini .
Dalam kasus yang tidak biasa itu
Berikut adalah fungsi yang sangat jelas yang menyimpan :
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)
}
Ini untuk saat Anda memiliki set karakter yang telah diperbaiki .
Tip berguna:
Tidak ada 0, o, O, i, dll ... karakter yang sering membingungkan manusia.
Ini sering dilakukan untuk kode pemesanan dan kode serupa yang akan digunakan pelanggan manusia.
repeating:count:
.
Sederhana dan Cepat - UUID (). UuidString
// Mengembalikan string yang dibuat dari UUID, seperti "E621E1F8-C36C-495A-93FC-0C247A3E6E5F"
public uarString: String {get}
Swift 3.0
let randomString = UUID().uuidString //0548CD07-7E2B-412B-AD69-5B2364644433
print(randomString.replacingOccurrences(of: "-", with: ""))
//0548CD077E2B412BAD695B2364644433
EDIT
Tolong jangan bingung dengan UIDevice.current.identifierForVendor?.uuidString
itu tidak akan memberikan nilai acak.
Versi 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
}
Pada dasarnya panggil metode ini yang akan menghasilkan string acak panjang bilangan bulat yang diserahkan ke fungsi. Untuk mengubah karakter yang mungkin, cukup edit string karakterString. Mendukung karakter unicode juga.
https://gist.github.com/gingofthesouth/54bea667b28a815b2fe33a4da986e327
EXC_BAD_INSTRUCTION
let random = randomString(16)
. EXC hanya di perangkat nyata dan saya tidak melihatnya di simulator dan itu terputus-putus di perangkat.
random % count
tidak tidak (selalu) membuat distribusi seragam. Jika ini relevan bagi Anda, lihat jawaban lain yang digunakan arc4random_uniform()
.
Untuk orang-orang yang tidak ingin mengetikkan seluruh rangkaian karakter:
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)
}
untuk 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
}
Acak murni Swift String
dari mana saja CharacterSet
.
Pemakaian: 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
}
}
The characters()
fungsi implementasi saya tercepat dikenal .
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
}
Saya bahkan lebih Swift-IER pelaksanaan pertanyaan:
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("")
}
Loop gratis, meskipun terbatas hingga 43 karakter. Jika Anda membutuhkan lebih banyak, itu dapat dimodifikasi. Pendekatan ini memiliki dua keunggulan dibandingkan hanya menggunakan UUID:
UUID()
hanya menghasilkan huruf besarUUID
paling panjang 36 karakter (termasuk 4 tanda hubung), tetapi hanya 32 karakter yang panjangnya. Jika Anda membutuhkan sesuatu yang lebih lama, atau tidak ingin menyertakan tanda hubung, gunakan base64EncodedString
pegangan iniJuga, fungsi ini memanfaatkan a UInt
untuk menghindari angka negatif.
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))
}
Menyebutnya secara berulang untuk memeriksa output:
for _ in 0...10 {
print(generateRandom(size: 32))
}
Yang menghasilkan:
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)
Masalah dengan respons terhadap "Saya perlu string acak" (dalam bahasa apa pun) praktis setiap solusi menggunakan spesifikasi primer cacat panjang string . Pertanyaan-pertanyaan itu sendiri jarang mengungkapkan mengapa string acak diperlukan, tetapi saya akan menantang Anda jarang membutuhkan string acak panjang, katakan 8. Apa yang Anda selalu butuhkan adalah sejumlah string unik , misalnya, untuk digunakan sebagai pengidentifikasi untuk beberapa tujuan.
Ada dua cara utama untuk mendapatkan string unik yang unik : deterministik (yang tidak acak) dan menyimpan / membandingkan (yang memberatkan). Apa yang kita lakukan? Kami menyerah hantu. Kami pergi dengan keunikan probabilistik sebagai gantinya. Artinya, kami menerima bahwa ada beberapa (betapapun kecil) risiko bahwa string kami tidak akan menjadi unik. Di sinilah pemahaman probabilitas tabrakan dan entropi sangat membantu.
Jadi saya akan ulangi kebutuhan yang tidak berubah sebagai membutuhkan sejumlah string dengan risiko pengulangan yang kecil. Sebagai contoh nyata, katakanlah Anda ingin menghasilkan potensi 5 juta ID. Anda tidak ingin menyimpan dan membandingkan setiap string baru, dan Anda ingin mereka menjadi acak, sehingga Anda menerima risiko berulang. Sebagai contoh, katakanlah risiko kurang dari 1 dalam satu triliun peluang berulang. Jadi berapa panjang tali yang Anda butuhkan? Nah, pertanyaan itu tidak ditentukan karena tergantung pada karakter yang digunakan. Tapi yang lebih penting, ini salah arah. Yang Anda butuhkan adalah spesifikasi entropi string, bukan panjangnya. Entropi dapat secara langsung terkait dengan probabilitas pengulangan dalam sejumlah string. Panjang string tidak bisa.
Dan di sinilah perpustakaan seperti EntropyString dapat membantu. Untuk menghasilkan ID acak yang memiliki peluang kurang dari 1 dalam satu triliun untuk diulang dalam 5 juta string menggunakan EntropyString
:
import EntropyString
let random = Random()
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
"Rrrj6pN4d6GBrFLH4"
EntropyString
menggunakan set karakter dengan 32 karakter secara default. Ada set karakter yang telah ditentukan sebelumnya, dan Anda dapat menentukan karakter Anda sendiri juga. Misalnya, membuat ID dengan entropi yang sama seperti di atas tetapi menggunakan karakter hex:
import EntropyString
let random = Random(.charSet16)
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
"135fe71aec7a80c02dce5"
Perhatikan perbedaan panjang string karena perbedaan jumlah karakter dalam set karakter yang digunakan. Risiko pengulangan dalam jumlah string potensial yang ditentukan adalah sama. Panjang string tidak. Dan yang terbaik dari semuanya, risiko pengulangan dan potensi jumlah string adalah eksplisit. Tidak perlu lagi menebak dengan panjang tali.
Jika string acak Anda harus acak-aman, gunakan ini:
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
}
Diperbarui untuk Swift 4. Gunakan variabel simpanan yang disimpan pada ekstensi kelas. Ini hanya dihitung sekali.
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
SWIFT 4
Menggunakan RandomNumberGenerator untuk kinerja yang lebih baik sebagai rekomendasi Apple
Penggunaan: String.random(20)
Hasil: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
}
}
Ini adalah solusi Swift -est yang bisa saya buat. 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
}