Move v3 and v5 UUID procs to uuid/legacy

This commit is contained in:
Feoramund
2024-06-22 13:04:21 -04:00
parent 9866b54d59
commit 3aa232a894
4 changed files with 158 additions and 140 deletions

View File

@@ -1,7 +1,5 @@
package uuid
import "core:crypto/legacy/md5"
import "core:crypto/legacy/sha1"
import "core:math/rand"
import "core:mem"
import "core:time"
@@ -50,71 +48,6 @@ generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil) -> (result: Identi
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 this 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 this 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 4 UUID.
@@ -136,74 +69,6 @@ generate_v4 :: proc() -> (result: Identifier) {
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 this 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[:])
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 this 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,
}
/*
Generate a version 6 UUID.

View File

@@ -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,
}

View File

@@ -63,6 +63,7 @@ import xml "core:encoding/xml"
import endian "core:encoding/endian"
import cbor "core:encoding/cbor"
import uuid "core:encoding/uuid"
import uuid_legacy "core:encoding/uuid/legacy"
import fmt "core:fmt"
import hash "core:hash"
@@ -239,6 +240,7 @@ _ :: flags
_ :: sysinfo
_ :: unicode
_ :: uuid
_ :: uuid_legacy
_ :: utf8
_ :: utf8string
_ :: utf16

View File

@@ -1,6 +1,7 @@
package test_core_uuid
import "core:encoding/uuid"
import uuid_legacy "core:encoding/uuid/legacy"
import "core:log"
import "core:testing"
import "core:time"
@@ -8,9 +9,9 @@ import "core:time"
@(test)
test_version_and_variant :: proc(t: ^testing.T) {
v1 := uuid.generate_v1(0)
v3 := uuid.generate_v3(uuid.Namespace_DNS, "")
v3 := uuid_legacy.generate_v3(uuid.Namespace_DNS, "")
v4 := uuid.generate_v4()
v5 := uuid.generate_v5(uuid.Namespace_DNS, "")
v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "")
v6 := uuid.generate_v6()
v7 := uuid.generate_v7()
@@ -29,7 +30,7 @@ test_version_and_variant :: proc(t: ^testing.T) {
}
@(test)
test_namespaced_uuids :: proc(t: ^testing.T) {
test_legacy_namespaced_uuids :: proc(t: ^testing.T) {
TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF"
Expected_Result :: struct {
@@ -45,8 +46,8 @@ test_namespaced_uuids :: proc(t: ^testing.T) {
}
for exp in Expected_Results {
v3 := uuid.generate_v3(exp.namespace, TEST_NAME)
v5 := uuid.generate_v5(exp.namespace, TEST_NAME)
v3 := uuid_legacy.generate_v3(exp.namespace, TEST_NAME)
v5 := uuid_legacy.generate_v5(exp.namespace, TEST_NAME)
v3_str := uuid.to_string(v3)
defer delete(v3_str)