我希望从一个随机字符串生成UUID字符串,以便相同的输入字符串生成相同的UUID。
我不关心从UUID获取输入字符串。我需要这样做是为了确定性地转换数据库中的键作为迁移的一部分,以便不同的客户端并行操作会收敛到相同的结果。
这个帖子中的接受答案提供了Java版本的答案,我需要Swift版本。
我希望从一个随机字符串生成UUID字符串,以便相同的输入字符串生成相同的UUID。
我不关心从UUID获取输入字符串。我需要这样做是为了确定性地转换数据库中的键作为迁移的一部分,以便不同的客户端并行操作会收敛到相同的结果。
这个帖子中的接受答案提供了Java版本的答案,我需要Swift版本。
官方的方法是使用版本5的UUID (RFC 4122 第4.3节):
4.3 用于创建基于名称的 UUID 的算法
版本3或5的 UUID 用于从“名称”中生成 UUID,这些“名称”来自某个“命名空间”,并在该命名空间内唯一。
处理过程是将字符串散列化,然后将其插入到 UUID 中。我将严格遵循规范,但我会标记您可以忽略的部分,即使如此,它仍将正确工作。
正如 matt 提到的那样,如果你只需要哈希,你可以直接使用 SHA。但如果你的系统确实需要 UUID,则应按照以下方式操作。
let namespace = "com.example.mygreatsystem:"
let inputString = "arandomstring"
let fullString = namespace + inputString
import CryptoKit
let hash = Insecure.SHA1.hash(data: Data(fullString.utf8)) // SHA-1 by spec
或者let hash = SHA256.hash(data: Data(fullString.utf8)) // SHA-2 is generally better
var truncatedHash = Array(hash.prefix(16))
truncatedHash[6] &= 0x0F // Clear version field
truncatedHash[6] |= 0x50 // Set version to 5
truncatedHash[8] &= 0x3F // Clear variant field
truncatedHash[8] |= 0x80 // Set variant to DCE 1.1
let uuidString = NSUUID(uuidBytes: truncatedHash).uuidString
@Nicolas Bachschmidt 的 UUIDKit 在 Swift 中实现了完整的 UUID v5。
它还支持 RFC 1808 中的所有命名空间,例如 NameSpace_URL:
import UUIDKit
UUID.v5(name: "http://example.com/index.html", namespace: .url)
因为它遵循规范,使用SHA-1并且输出与其他平台实现相匹配,所以上述行的输出与此Python代码的输出值相同:
import uuid
uuid.uuid5(uuid.NAMESPACE_URL, 'http://example.com/index.html')