从命名空间生成 UUID?

MCM*_*tan 4 uuid ios swift

尝试基于 2 个唯一字符串生成客户端 ID。这最终应该与服务器中生成的 UUID 相同,来自相同的 Ids。

使用 Javascript,它看起来像这样:

uuidv5(id1 + id2 , uuidv5.DNS);
Run Code Online (Sandbox Code Playgroud)

似乎找不到在 Swift 上生成它的方法,NSUUID 只能从无到有生成 UUID

NSUUID().uuidString
Run Code Online (Sandbox Code Playgroud)

我正在寻找这样的东西:

NSUUID(namespace: id1 + id2).uuidString
Run Code Online (Sandbox Code Playgroud)

编辑

例子:

let sorted = ["5a23dbfb2626b400190998fc", "5pCAvA7h8k9JuErRn"]
let appended = sorted.seperaredStringBy("-")
let result = uuidv5(appended , uuidv5.DNS)

//results:
2522b097-8532-548e-a18b-9366c6511b5e
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 9

据我所知,Swift 标准库或 Foundation 框架没有针对第 5 版 UUID 的内置方法。

这是第 3 版和第 5 版 UUID 的可能实现,取自Generating v5 UUID 中的描述什么是名称和命名空间?以及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: $0, 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
    }
}
Run Code Online (Sandbox Code Playgroud)

示例 1(您的情况):

let uuid = UUID(version: .v5, name: "5a23dbfb2626b400190998fc-5pCAvA7h8k9JuErRn", nameSpace: .dns)
print(uuid) // 2522B097-8532-548E-A18B-9366C6511B5E
Run Code Online (Sandbox Code Playgroud)

示例 2(来自 RFC 4122 中的附录 B,已在勘误表中更正):

let uuid = UUID(version: .v3, name: "www.widgets.com", nameSpace: .dns)
print(uuid) //3D813CBB-47FB-32BA-91DF-831E1593AC29
Run Code Online (Sandbox Code Playgroud)

  • 你太棒了。谢谢。 (2认同)