Skip to content

Instantly share code, notes, and snippets.

@vzsg
Created June 26, 2019 14:55
Show Gist options
  • Save vzsg/ec21f7812622be17b51599ed7ac51a9c to your computer and use it in GitHub Desktop.
Save vzsg/ec21f7812622be17b51599ed7ac51a9c to your computer and use it in GitHub Desktop.
UUIDv5 using Vapor3's Crypto
// This is a direct port of https://github.com/download13/uuidv5 to Swift
import Foundation
import Crypto
public extension UUID {
enum Namespace {
case dns
case url
case oid
case x500
case null
case custom(UUID)
public var uuid: UUID {
switch self {
case .dns:
return UUID(uuidString: "6ba7b810-9dad-11d1-80b4-00c04fd430c8")!
case .url:
return UUID(uuidString: "6ba7b811-9dad-11d1-80b4-00c04fd430c8")!
case .oid:
return UUID(uuidString: "6ba7b812-9dad-11d1-80b4-00c04fd430c8")!
case .x500:
return UUID(uuidString: "6ba7b814-9dad-11d1-80b4-00c04fd430c8")!
case .null:
return UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
case .custom(let uuid):
return uuid
}
}
}
init(namespace: Namespace, name: String) throws {
let rawNamespace = namespace.uuid.uuid
var c = Data([
rawNamespace.0,
rawNamespace.1,
rawNamespace.2,
rawNamespace.3,
rawNamespace.4,
rawNamespace.5,
rawNamespace.6,
rawNamespace.7,
rawNamespace.8,
rawNamespace.9,
rawNamespace.10,
rawNamespace.11,
rawNamespace.12,
rawNamespace.13,
rawNamespace.14,
rawNamespace.15
])
c.append(name.data(using: .utf8) ?? Data())
let digest = try SHA1.hash(c)
let result: uuid_t = (
digest[0],
digest[1],
digest[2],
digest[3],
digest[4],
digest[5],
(digest[6] & 0x0f) | 0x50, // version, 4 most significant bits are set to version 5 (0101)
digest[7],
(digest[8] & 0x3f) | 0x80, // clock_seq_hi_and_reserved, 2msb are set to 10
digest[9],
digest[10],
digest[11],
digest[12],
digest[13],
digest[14],
digest[15]
)
self.init(uuid: result)
}
}
import App
import XCTest
final class UUIDv5Tests: XCTestCase {
func testUUIDv5() throws {
XCTAssertEqual(try UUID(namespace: .dns, name: "www.example.org"), UUID("74738ff5-5367-5958-9aee-98fffdcd1876"))
XCTAssertEqual(try UUID(namespace: .url, name: "http://example.org/page"), UUID("6b19973b-8154-5782-bca0-15e6b730ca00"))
XCTAssertEqual(try UUID(namespace: .oid, name: "1.3.6.1.2.1"), UUID("2a7086de-bbf9-5cb9-9a66-a9e928c26504"))
XCTAssertEqual(try UUID(namespace: .x500, name: "uid=user,ou=people,dc=example,dc=com"), UUID("5324d252-c0de-5365-a19c-389275462a9c"))
}
static let allTests = [
("testUUIDv5", testUUIDv5)
]
}
@vzsg
Copy link
Author

vzsg commented Jun 26, 2019

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment