我需要在Swift中生成BSON格式的带时间戳的对象ID。 ObjectID适用于Mongo DB。如何实现这一目标?
答案 0 :(得分:4)
一个天真的解决方案看起来像这样:
func objectId() -> String {
let time = String(Int(NSDate().timeIntervalSince1970), radix: 16, uppercase: false)
let machine = String(arc4random_uniform(900000) + 100000)
let pid = String(arc4random_uniform(9000) + 1000)
let counter = String(arc4random_uniform(900000) + 100000)
return time + machine + pid + counter
}
MongoDB docs指定有关ObjectID的以下内容
以上将满足该要求。但是,它只会为时间戳以外的部分生成随机数字符。一个完美的解决方案是使用NSProcessInfo
和NSUUID
之类的apis作为机器和pid。它还必须跟踪一个计数器。
答案 1 :(得分:0)
从MongoDB文档中,使用以下方法生成ObjectId:
您可以使用实现上述内容的此类。
class ObjectId {
private init() {}
static let shared = ObjectId()
private var counter = Int.random(in: 0...0xffffff)
private func incrementCounter() {
if (counter >= 0xffffff) {
counter = 0
} else {
counter += 1
}
}
func generate() -> String {
let time = ~(~Int(NSDate().timeIntervalSince1970))
let random = Int.random(in: 0...0xffffffffff)
let i = counter
incrementCounter()
var byteArray = Array<UInt8>.init(repeating: 0, count: 12)
byteArray[0] = UInt8((time >> 24) & 0xff)
byteArray[1] = UInt8((time >> 16) & 0xff)
byteArray[2] = UInt8((time >> 8) & 0xff)
byteArray[3] = UInt8(time & 0xff)
byteArray[4] = UInt8((random >> 32) & 0xff)
byteArray[5] = UInt8((random >> 24) & 0xff)
byteArray[6] = UInt8((random >> 16) & 0xff)
byteArray[7] = UInt8((random >> 8) & 0xff)
byteArray[8] = UInt8(random & 0xff)
byteArray[9] = UInt8((i >> 16) & 0xff)
byteArray[10] = UInt8((i >> 8) & 0xff)
byteArray[11] = UInt8(i & 0xff)
let id = byteArray
.map({ String($0, radix: 16, uppercase: false)
.padding(toLength: 2, withPad: "0", startingAt: 0) })
.joined()
return id
}
}
以下代码将生成一个新的ObjectId字符串:
ObjectId.shared.generate()