답변:
스위프트 4.2 업데이트
Swift 4.2는 임의의 값과 요소를 처리 할 때 크게 개선되었습니다. 당신은 할 수 있습니다 여기 개선에 대한 자세한 내용 . 다음은 몇 줄로 축소 된 방법입니다.
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
스위프트 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
}
원래 답변 :
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
}
다음 은 Swiftier 구문에서 바로 사용할 수있는 솔루션 입니다 . 간단히 복사하여 붙여 넣을 수 있습니다.
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
}
좀 더 편리한 기능을 가진 프레임 워크 를 선호한다면 내 프로젝트 HandySwift를 자유롭게 확인하십시오 . 또한 임의의 영숫자 문자열에 대한 아름다운 솔루션이 포함되어 있습니다 .
String(randomWithLength: 8, allowedCharactersType: .alphaNumeric) // => "2TgM5sUG"
다음과 같은 방법으로도 사용할 수 있습니다.
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
}
}
간단한 사용법 :
let randomString = String.random()
스위프트 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
}
}
스위프트 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
}
}
빠른:
let randomString = NSUUID().uuidString
특이한 경우에는
다음은 캐시 하는 매우 명확한 기능입니다 .
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)
}
이것은 당신이 알려진 고정 된 경우입니다 문자 집합을.
편리한 팁 :
인간이 종종 혼동하는 문자는 0, o, O, i 등이 없습니다.
이는 종종 사람 고객이 사용할 예약 코드 및 유사한 코드에 대해 수행됩니다.
repeating:count:
.
간단하고 빠른 - . UUID () uuidString
// UUID에서 생성 된 문자열 (예 : "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")을 반환합니다.
공용 var uuidString : 문자열 {get}
스위프트 3.0
let randomString = UUID().uuidString //0548CD07-7E2B-412B-AD69-5B2364644433
print(randomString.replacingOccurrences(of: "-", with: ""))
//0548CD077E2B412BAD695B2364644433
편집하다
하지 혼동 마십시오 과 UIDevice.current.identifierForVendor?.uuidString
임의의 값을 제공하지 않습니다 그것.
함께 스위프트 4.2 당신의 가장 좋은 방법은 당신이 원하는 문자가 포함 된 문자열을 생성하고 사용하는 것입니다 randomElement를 각 문자를 선택하기 :
let length = 32
let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomCharacters = (0..<length).map{_ in characters.randomElement()!}
let randomString = String(randomCharacters)
이러한 변경 사항에 대한 자세한 내용은 여기를 참조하십시오 .
스위프트 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
}
기본적으로이 메서드를 호출하여 함수에 전달 된 정수의 길이로 임의의 문자열을 생성합니다. 가능한 문자를 변경하려면 charactersString 문자열을 편집하십시오. 유니 코드 문자도 지원합니다.
https://gist.github.com/gingofthesouth/54bea667b28a815b2fe33a4da986e327
EXC_BAD_INSTRUCTION
let random = randomString(16)
. EXC는 실제 장치에만 있었고 시뮬레이터에서 보지 못했으며 장치에서 간헐적이었습니다.
random % count
하지 않습니다 . 이것이 귀하와 관련이 있으면를 사용하는 다른 답변을보십시오 arc4random_uniform()
.
전체 문자 집합을 입력하지 않으려는 사람들을 위해 :
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)
}
스위프트 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
}
순수 스위프트 임의의 String
어떤에서CharacterSet
.
용법: 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
}
}
이 characters()
기능은 내가 가장 빠르게 알려진 구현 입니다.
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
}
내 더욱 신속한-IER 질문의 구현 :
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("")
}
루프는 무료이지만 43 자로 제한됩니다. 더 필요한 경우 수정할 수 있습니다. 이 방법은 UUID를 단독 사용하는 것보다 두 가지 장점이 있습니다.
UUID()
만 생성 하므로 소문자를 사용하여 더 큰 엔트로피UUID
는 최대 36 자 (4 개의 하이픈 포함)이지만 최대 32 자입니다. 더 긴 것이 필요하거나 하이픈을 포함하지 않으려면 base64EncodedString
핸들을 사용하여또한이 함수는 a UInt
를 사용 하여 음수를 피합니다.
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))
}
출력을 확인하기 위해 루프에서 호출 :
for _ in 0...10 {
print(generateRandom(size: 32))
}
어느 생산 :
Nzk3NjgzMTdBQ0FBNDFCNzk2MDRENzZF
MUI5RURDQzE1RTdCNDA3RDg2MTI4QkQx
M0I3MjJBRjVFRTYyNDFCNkI5OUM1RUVC
RDA1RDZGQ0IzQjI1NDdGREI3NDgxM0Mx
NjcyNUQyOThCNzhCNEVFQTk1RTQ3NTIy
MDkwRTQ0RjFENUFGNEFDOTgyQTUxODI0
RDU2OTNBOUJGMDE4NDhEODlCNEQ1NjZG
RjM2MTUxRjM4RkY3NDU2OUFDOTI0Nzkz
QzUwOTE1N0U1RDVENDE4OEE5NTM2Rjcy
Nzk4QkMxNUJEMjYwNDJDQjhBQkY5QkY5
ODhFNjU0MDVEMUI2NEI5QUIyNjNCNkVF
"임의의 문자열이 필요합니다" 질문에 대한 응답의 문제 (언어가 무엇이든)는 실제로 모든 솔루션에 결함이있는 기본 길이 인 기본 문자열을 사용한다는 것 입니다. 임의의 문자열이 필요한 이유를 질문 자체가 거의 공개하지 않습니다,하지만 난 당신이 변함없이 필요가 몇 개의 무엇 8. 말, 당신은 거의 길이의 임의의 문자열을 필요로하지 도전 할 고유의 문자열이 어떤 목적을위한 식별자로 사용, 예를 들어,.
엄격하게 고유 한 문자열 을 얻는 두 가지 주요 방법이 있습니다 . 우리는 무엇을해야합니까? 우리는 유령을 포기합니다. 우리는 함께 갈 확률 고유성 대신. 즉, 우리는 우리의 끈이 독특하지 않을 위험이 있음을 인정합니다. 충돌 확률 과 엔트로피를 이해하는 것이 도움이됩니다.
따라서 반복의 위험이 적은 몇 개의 문자열이 필요하다고 변하지 않는 필요성을 다시 말하겠습니다. 구체적인 예로, 5 백만 개의 잠재적 인 ID를 생성하려고한다고 가정하겠습니다. 각각의 새 문자열을 저장하고 비교하고 싶지 않으며 임의의 문자열을 원하므로 반복 위험이 있습니다. 예를 들어, 1 조 회 반복 가능성이 1 미만인 위험을 가정 해 봅시다. 그래서 어떤 길이의 문자열이 필요합니까? 글쎄, 그 질문은 사용 된 문자에 따라 다르므로 지정되지 않았습니다. 그러나 더 중요한 것은 잘못 인도 된 것입니다. 필요한 것은 길이가 아닌 문자열의 엔트로피 사양입니다. 엔트로피는 몇 개의 문자열에서 반복 확률과 직접 관련 될 수 있습니다. 문자열 길이는 할 수 없습니다.
EntropyString 과 같은 라이브러리 가 도움이 될 수 있습니다. 다음을 사용하여 5 백만 개의 문자열에서 1 조 건의 반복 확률로 1 미만의 임의 ID를 생성하려면 EntropyString
다음을 사용하십시오 .
import EntropyString
let random = Random()
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
"Rrrj6pN4d6GBrFLH4"
EntropyString
기본적으로 32 자 문자 세트를 사용합니다. 사전 정의 된 다른 문자 세트가 있으며 고유 한 문자도 지정할 수 있습니다. 예를 들어, 위와 동일하지만 16 진 문자를 사용하여 ID를 생성합니다.
import EntropyString
let random = Random(.charSet16)
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
"135fe71aec7a80c02dce5"
사용 된 문자 세트의 총 문자 수 차이로 인해 문자열 길이의 차이에 유의하십시오. 지정된 수의 잠재적 인 문자열에서 반복 위험은 동일합니다. 문자열 길이는 다릅니다. 그리고 무엇보다도 반복의 위험과 잠재적 인 문자열 수는 명백합니다. 더 이상 문자열 길이를 추측하지 않아도됩니다.
임의의 문자열이 안전한 임의의 경우 다음을 사용하십시오.
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
}
Swift 4 용으로 업데이트되었습니다. 클래스 확장에 지연 저장 변수를 사용하십시오. 이것은 한 번만 계산됩니다.
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
스위프트 4
Apple 권장 사항으로 성능 향상을 위해 RandomNumberGenerator 사용
사용법 : String.random(20)
결과 :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
}
}
이것이 내가 생각해 낼 수 있는 Swift- est 솔루션입니다. 스위프트 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
}