我如何在Swift中生成一个随机的字母数字字符串?
当前回答
来自任何字符集的纯Swift随机字符串。
用法:CharacterSet.alphanumerics。randomString(长度: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()函数是我所知道的最快的实现。
其他回答
如果您只需要一个唯一标识符UUID()。uuidString可以满足您的需求。
回答“我需要随机字符串”问题的问题(无论哪种语言)实际上每个解决方案都使用了有缺陷的字符串长度的主要规范。问题本身很少揭示为什么需要随机字符串,但我想挑战你很少需要长度为8的随机字符串。您总是需要一些唯一的字符串,例如,用于某种目的的标识符。
有两种主要的方法来获得严格唯一的字符串:确定性(不是随机的)和存储/比较(繁琐的)。我们该怎么办?我们放弃了。我们用概率唯一性来代替。也就是说,我们接受存在一些(无论多么小)的风险,即我们的字符串不是唯一的。这就是为什么理解碰撞概率和熵是有帮助的。
So I'll rephrase the invariable need as needing some number of strings with a small risk of repeat. As a concrete example, let's say you want to generate a potential of 5 million IDs. You don't want to store and compare each new string, and you want them to be random, so you accept some risk of repeat. As example, let's say a risk of less than 1 in a trillion chance of repeat. So what length of string do you need? Well, that question is underspecified as it depends on the characters used. But more importantly, it's misguided. What you need is a specification of the entropy of the strings, not their length. Entropy can be directly related to the probability of a repeat in some number of strings. String length can't.
这就是像EntropyString这样的库可以帮助的地方。使用EntropyString在500万个字符串中生成重复概率小于1万亿分之一的随机id:
import EntropyString
let random = Random()
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
" Rrrj6pN4d6GBrFLH4 "
EntropyString默认使用32个字符的字符集。还有其他预定义的字符集,您也可以指定自己的字符。例如,生成与上面相同熵的id,但使用十六进制字符:
import EntropyString
let random = Random(.charSet16)
let bits = Entropy.bits(for: 5.0e6, risk: 1.0e12)
random.string(bits: bits)
“135fe71AEC7A80C02DCE5”
请注意由于所使用的字符集中字符总数的不同而导致的字符串长度的差异。在指定数量的潜在字符串中重复的风险相同。字符串长度不是。最重要的是,重复的风险和字符串的潜在数量是明确的。没有更多的猜测字符串长度。
我对这个问题的更快速的回答是:
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("")
}
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
}
你也可以这样使用它:
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()
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
}
}
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
}
}
推荐文章
- 如果性能很重要,我应该使用Java的String.format()吗?
- 我如何在Swift中解析/创建一个以分数秒UTC时区(ISO 8601, RFC 3339)格式化的日期时间戳?
- 我如何分割一个字符串由一个多字符分隔符在c# ?
- 如何删除Python中的前导空白?
- 如何在Typescript中解析JSON字符串
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- 用javascript检查输入字符串中是否包含数字
- 如何使用@Binding变量实现自定义初始化
- Swift设置为Array
- 如何设置回退按钮文本在Swift
- 我如何能在Swift扩展类型化数组?
- Swift类错误:属性未在super处初始化。init调用
- Java:检查enum是否包含给定的字符串?
- 用PHP删除字符串的前4个字符