从名称 space 生成 UUID?
Generate UUID from name space?
正在尝试根据 2 个唯一字符串生成客户端 ID。
这最终应该与服务器中生成的 UUID 相同,来自相同的 ID。
Javascript 看起来像这样:
uuidv5(id1 + id2 , uuidv5.DNS);
似乎无法在 Swift 上找到生成它的方法,NSUUID 只能从无到有生成 UUID
NSUUID().uuidString
我正在寻找这样的东西:
NSUUID(namespace: id1 + id2).uuidString
编辑
示例:
let sorted = ["5a23dbfb2626b400190998fc", "5pCAvA7h8k9JuErRn"]
let appended = sorted.seperaredStringBy("-")
let result = uuidv5(appended , uuidv5.DNS)
//results:
2522b097-8532-548e-a18b-9366c6511b5e
据我所知,Swift 标准库或 Foundation 框架没有针对版本 5 UUID 的内置方法。
这是第 3 版和第 5 版 UUID 的可能实现,摘自 Generating v5 UUID. What is name and namespace? and the reference implementation in RFC 4122 的描述。
(针对 Swift 4 及更高版本进行了更新。)
import Foundation
import CommonCrypto
extension UUID {
enum UUIDVersion: Int {
case v3 = 3
case v5 = 5
}
enum UUIDv5NameSpace: String {
case dns = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
case url = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
case oid = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
case x500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
}
init(version: UUIDVersion, name: String, nameSpace: UUIDv5NameSpace) {
// Get UUID bytes from name space:
var spaceUID = UUID(uuidString: nameSpace.rawValue)!.uuid
var data = withUnsafePointer(to: &spaceUID) { [count = MemoryLayout.size(ofValue: spaceUID)] in
Data(bytes: [=10=], count: count)
}
// Append name string in UTF-8 encoding:
data.append(contentsOf: name.utf8)
// Compute digest (MD5 or SHA1, depending on the version):
var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> Void in
switch version {
case .v3:
_ = CC_MD5(ptr.baseAddress, CC_LONG(data.count), &digest)
case .v5:
_ = CC_SHA1(ptr.baseAddress, CC_LONG(data.count), &digest)
}
}
// Set version bits:
digest[6] &= 0x0F
digest[6] |= UInt8(version.rawValue) << 4
// Set variant bits:
digest[8] &= 0x3F
digest[8] |= 0x80
// Create UUID from digest:
self = NSUUID(uuidBytes: digest) as UUID
}
}
示例 1(您的情况):
let uuid = UUID(version: .v5, name: "5a23dbfb2626b400190998fc-5pCAvA7h8k9JuErRn", nameSpace: .dns)
print(uuid) // 2522B097-8532-548E-A18B-9366C6511B5E
示例 2(来自 RFC 4122 中的附录 B,在 Errata 中更正):
let uuid = UUID(version: .v3, name: "www.widgets.com", nameSpace: .dns)
print(uuid) //3D813CBB-47FB-32BA-91DF-831E1593AC29
objc 版本,以备不时之需。
+ (CBUUID *)UUIDWithNamespace:(NSString *)namespace name:(NSString *)name version:(int)version
{
if (namespace.length <= 0 || name == nil ) { return nil; }
if (!(version == 3 || version == 5)) { return nil; }
CBUUID *namespaceUUID = [CBUUID UUIDWithString:namespace];
if (namespaceUUID == nil) { return nil; }
NSMutableData *data = [[NSMutableData alloc] init];
[data appendData:namespaceUUID.data];
[data appendData:[name dataUsingEncoding:NSUTF8StringEncoding]];
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
if (version == 3) {
CC_MD5(data.bytes, (int)data.length, hash);
} else if (version == 5) {
CC_SHA1(data.bytes, (int)data.length, hash);
}
unsigned char result[16];
memcpy(result, hash, 16);
result[6] &= 0x0F;
result[6] |= (((unsigned char)version) << 4);
result[8] &= 0x3F;
result[8] |= 0x80;
return [CBUUID UUIDWithData:[NSData dataWithBytes:result length:16]];
}
正在尝试根据 2 个唯一字符串生成客户端 ID。 这最终应该与服务器中生成的 UUID 相同,来自相同的 ID。
Javascript 看起来像这样:
uuidv5(id1 + id2 , uuidv5.DNS);
似乎无法在 Swift 上找到生成它的方法,NSUUID 只能从无到有生成 UUID
NSUUID().uuidString
我正在寻找这样的东西:
NSUUID(namespace: id1 + id2).uuidString
编辑
示例:
let sorted = ["5a23dbfb2626b400190998fc", "5pCAvA7h8k9JuErRn"]
let appended = sorted.seperaredStringBy("-")
let result = uuidv5(appended , uuidv5.DNS)
//results:
2522b097-8532-548e-a18b-9366c6511b5e
据我所知,Swift 标准库或 Foundation 框架没有针对版本 5 UUID 的内置方法。
这是第 3 版和第 5 版 UUID 的可能实现,摘自 Generating v5 UUID. What is name and namespace? and the reference implementation in RFC 4122 的描述。
(针对 Swift 4 及更高版本进行了更新。)
import Foundation
import CommonCrypto
extension UUID {
enum UUIDVersion: Int {
case v3 = 3
case v5 = 5
}
enum UUIDv5NameSpace: String {
case dns = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
case url = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
case oid = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
case x500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
}
init(version: UUIDVersion, name: String, nameSpace: UUIDv5NameSpace) {
// Get UUID bytes from name space:
var spaceUID = UUID(uuidString: nameSpace.rawValue)!.uuid
var data = withUnsafePointer(to: &spaceUID) { [count = MemoryLayout.size(ofValue: spaceUID)] in
Data(bytes: [=10=], count: count)
}
// Append name string in UTF-8 encoding:
data.append(contentsOf: name.utf8)
// Compute digest (MD5 or SHA1, depending on the version):
var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> Void in
switch version {
case .v3:
_ = CC_MD5(ptr.baseAddress, CC_LONG(data.count), &digest)
case .v5:
_ = CC_SHA1(ptr.baseAddress, CC_LONG(data.count), &digest)
}
}
// Set version bits:
digest[6] &= 0x0F
digest[6] |= UInt8(version.rawValue) << 4
// Set variant bits:
digest[8] &= 0x3F
digest[8] |= 0x80
// Create UUID from digest:
self = NSUUID(uuidBytes: digest) as UUID
}
}
示例 1(您的情况):
let uuid = UUID(version: .v5, name: "5a23dbfb2626b400190998fc-5pCAvA7h8k9JuErRn", nameSpace: .dns)
print(uuid) // 2522B097-8532-548E-A18B-9366C6511B5E
示例 2(来自 RFC 4122 中的附录 B,在 Errata 中更正):
let uuid = UUID(version: .v3, name: "www.widgets.com", nameSpace: .dns)
print(uuid) //3D813CBB-47FB-32BA-91DF-831E1593AC29
objc 版本,以备不时之需。
+ (CBUUID *)UUIDWithNamespace:(NSString *)namespace name:(NSString *)name version:(int)version
{
if (namespace.length <= 0 || name == nil ) { return nil; }
if (!(version == 3 || version == 5)) { return nil; }
CBUUID *namespaceUUID = [CBUUID UUIDWithString:namespace];
if (namespaceUUID == nil) { return nil; }
NSMutableData *data = [[NSMutableData alloc] init];
[data appendData:namespaceUUID.data];
[data appendData:[name dataUsingEncoding:NSUTF8StringEncoding]];
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
if (version == 3) {
CC_MD5(data.bytes, (int)data.length, hash);
} else if (version == 5) {
CC_SHA1(data.bytes, (int)data.length, hash);
}
unsigned char result[16];
memcpy(result, hash, 16);
result[6] &= 0x0F;
result[6] |= (((unsigned char)version) << 4);
result[8] &= 0x3F;
result[8] |= 0x80;
return [CBUUID UUIDWithData:[NSData dataWithBytes:result length:16]];
}