|
@@ -0,0 +1,150 @@
|
|
|
+/*
|
|
|
+package uuid/legacy implements versions 3 and 5 of UUID generation, both of
|
|
|
+which are using hashing algorithms (MD5 and SHA1, respectively) that are known
|
|
|
+these days to no longer be secure.
|
|
|
+*/
|
|
|
+package uuid_legacy
|
|
|
+
|
|
|
+import "base:runtime"
|
|
|
+import "core:crypto/legacy/md5"
|
|
|
+import "core:crypto/legacy/sha1"
|
|
|
+import "core:encoding/uuid"
|
|
|
+
|
|
|
+Identifier :: uuid.Identifier
|
|
|
+VERSION_BYTE_INDEX :: uuid.VERSION_BYTE_INDEX
|
|
|
+VARIANT_BYTE_INDEX :: uuid.VARIANT_BYTE_INDEX
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+Generate a version 3 UUID.
|
|
|
+
|
|
|
+This UUID is generated from a name within a namespace.
|
|
|
+MD5 is used to hash the name with the namespace to produce the UUID.
|
|
|
+
|
|
|
+Inputs:
|
|
|
+- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
|
+ This can be any one of the `Namespace_*` values provided in the `uuid` package.
|
|
|
+- name: The byte slice used to generate the name on top of the namespace.
|
|
|
+
|
|
|
+Returns:
|
|
|
+- result: The generated UUID.
|
|
|
+*/
|
|
|
+generate_v3_bytes :: proc(
|
|
|
+ namespace: Identifier,
|
|
|
+ name: []byte,
|
|
|
+) -> (
|
|
|
+ result: Identifier,
|
|
|
+) {
|
|
|
+ namespace := namespace
|
|
|
+
|
|
|
+ ctx: md5.Context
|
|
|
+ md5.init(&ctx)
|
|
|
+ md5.update(&ctx, namespace[:])
|
|
|
+ md5.update(&ctx, name)
|
|
|
+ md5.final(&ctx, result[:])
|
|
|
+
|
|
|
+ result[VERSION_BYTE_INDEX] &= 0x0F
|
|
|
+ result[VERSION_BYTE_INDEX] |= 0x30
|
|
|
+
|
|
|
+ result[VARIANT_BYTE_INDEX] &= 0x3F
|
|
|
+ result[VARIANT_BYTE_INDEX] |= 0x80
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+Generate a version 3 UUID.
|
|
|
+
|
|
|
+This UUID is generated from a name within a namespace.
|
|
|
+MD5 is used to hash the name with the namespace to produce the UUID.
|
|
|
+
|
|
|
+Inputs:
|
|
|
+- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
|
+ This can be any one of the `Namespace_*` values provided in the `uuid` package.
|
|
|
+- name: The string used to generate the name on top of the namespace.
|
|
|
+
|
|
|
+Returns:
|
|
|
+- result: The generated UUID.
|
|
|
+*/
|
|
|
+generate_v3_string :: proc(
|
|
|
+ namespace: Identifier,
|
|
|
+ name: string,
|
|
|
+) -> (
|
|
|
+ result: Identifier,
|
|
|
+) {
|
|
|
+ return generate_v3_bytes(namespace, transmute([]byte)name)
|
|
|
+}
|
|
|
+
|
|
|
+generate_v3 :: proc {
|
|
|
+ generate_v3_bytes,
|
|
|
+ generate_v3_string,
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+Generate a version 5 UUID.
|
|
|
+
|
|
|
+This UUID is generated from a name within a namespace.
|
|
|
+SHA1 is used to hash the name with the namespace to produce the UUID.
|
|
|
+
|
|
|
+Inputs:
|
|
|
+- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
|
+ This can be any one of the `Namespace_*` values provided in the `uuid` package.
|
|
|
+- name: The byte slice used to generate the name on top of the namespace.
|
|
|
+
|
|
|
+Returns:
|
|
|
+- result: The generated UUID.
|
|
|
+*/
|
|
|
+generate_v5_bytes :: proc(
|
|
|
+ namespace: Identifier,
|
|
|
+ name: []byte,
|
|
|
+) -> (
|
|
|
+ result: Identifier,
|
|
|
+) {
|
|
|
+ namespace := namespace
|
|
|
+ digest: [sha1.DIGEST_SIZE]byte
|
|
|
+
|
|
|
+ ctx: sha1.Context
|
|
|
+ sha1.init(&ctx)
|
|
|
+ sha1.update(&ctx, namespace[:])
|
|
|
+ sha1.update(&ctx, name)
|
|
|
+ sha1.final(&ctx, digest[:])
|
|
|
+
|
|
|
+ runtime.mem_copy_non_overlapping(&result, &digest, 16)
|
|
|
+
|
|
|
+ result[VERSION_BYTE_INDEX] &= 0x0F
|
|
|
+ result[VERSION_BYTE_INDEX] |= 0x50
|
|
|
+
|
|
|
+ result[VARIANT_BYTE_INDEX] &= 0x3F
|
|
|
+ result[VARIANT_BYTE_INDEX] |= 0x80
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+Generate a version 5 UUID.
|
|
|
+
|
|
|
+This UUID is generated from a name within a namespace.
|
|
|
+SHA1 is used to hash the name with the namespace to produce the UUID.
|
|
|
+
|
|
|
+Inputs:
|
|
|
+- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
|
+ This can be any one of the `Namespace_*` values provided in the `uuid` package.
|
|
|
+- name: The string used to generate the name on top of the namespace.
|
|
|
+
|
|
|
+Returns:
|
|
|
+- result: The generated UUID.
|
|
|
+*/
|
|
|
+generate_v5_string :: proc(
|
|
|
+ namespace: Identifier,
|
|
|
+ name: string,
|
|
|
+) -> (
|
|
|
+ result: Identifier,
|
|
|
+) {
|
|
|
+ return generate_v5_bytes(namespace, transmute([]byte)name)
|
|
|
+}
|
|
|
+
|
|
|
+generate_v5 :: proc {
|
|
|
+ generate_v5_bytes,
|
|
|
+ generate_v5_string,
|
|
|
+}
|
|
|
+
|