aboutsummaryrefslogtreecommitdiff
path: root/core/encoding/uuid
diff options
context:
space:
mode:
authorFeoramund <161657516+Feoramund@users.noreply.github.com>2024-06-22 12:54:39 -0400
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2024-06-22 18:21:31 -0400
commit9866b54d59721d62137f2a8279f015aeef0f7a4f (patch)
tree30945c440bd356a73d754132d3222152428320cc /core/encoding/uuid
parent525bfca4ef53916ca99f0c5cd4a1371ba6756c95 (diff)
Add version 6 UUID generation
Diffstat (limited to 'core/encoding/uuid')
-rw-r--r--core/encoding/uuid/generation.odin46
-rw-r--r--core/encoding/uuid/reading.odin20
2 files changed, 65 insertions, 1 deletions
diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin
index 29944dcb5..08fd84c0c 100644
--- a/core/encoding/uuid/generation.odin
+++ b/core/encoding/uuid/generation.odin
@@ -205,6 +205,52 @@ generate_v5 :: proc {
}
/*
+Generate a version 6 UUID.
+
+Inputs:
+- clock_seq: The clock sequence from version 1, now made optional.
+ If unspecified, it will be replaced with random bits.
+- node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system.
+ If one is not provided or available, 48 bits of random state will take its place.
+
+Returns:
+- result: The generated UUID.
+*/
+generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil) -> (result: Identifier) {
+ unix_time_in_hns_intervals := time.to_unix_nanoseconds(time.now()) / 100
+
+ timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals)
+
+ result |= transmute(Identifier)(timestamp & 0x0FFFFFFF_FFFFF000 << 68)
+ result |= transmute(Identifier)(timestamp & 0x00000000_00000FFF << 64)
+
+ if realized_clock_seq, ok := clock_seq.?; ok {
+ assert(realized_clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383.")
+ result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8)
+ result[9] = cast(u8)realized_clock_seq
+ } else {
+ temporary: [2]u8
+ bytes_generated := rand.read(temporary[:])
+ assert(bytes_generated == 2, "RNG failed to generate 2 bytes for UUID v1.")
+ result[8] |= cast(u8)temporary[0] & 0x3F
+ result[9] = cast(u8)temporary[1]
+ }
+
+ if realized_node, ok := node.?; ok {
+ mutable_node := realized_node
+ mem.copy_non_overlapping(&result[10], &mutable_node[0], 6)
+ } else {
+ bytes_generated := rand.read(result[10:])
+ assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.")
+ }
+
+ result[VERSION_BYTE_INDEX] |= 0x60
+ result[VARIANT_BYTE_INDEX] |= 0x80
+
+ return
+}
+
+/*
Generate a version 7 UUID.
This UUID will be pseudorandom, save for 6 pre-determined version and variant
diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin
index f31ae2bcd..3b2c48011 100644
--- a/core/encoding/uuid/reading.odin
+++ b/core/encoding/uuid/reading.odin
@@ -99,7 +99,7 @@ variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bo
}
/*
-Get the clock sequence of a version 1 UUID.
+Get the clock sequence of a version 1 or version 6 UUID.
Inputs:
- id: The identifier.
@@ -152,6 +152,24 @@ time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) {
}
/*
+Get the timestamp of a version 6 UUID.
+
+Inputs:
+- id: The identifier.
+
+Returns:
+- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15.
+*/
+time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: u64) {
+ temporary := transmute(u128be)id
+
+ timestamp |= cast(u64)(temporary & 0xFFFFFFFF_FFFF0000_00000000_00000000 >> 68)
+ timestamp |= cast(u64)(temporary & 0x00000000_00000FFF_00000000_00000000 >> 64)
+
+ return timestamp
+}
+
+/*
Get the timestamp of a version 7 UUID.
Inputs: