|
@@ -17,7 +17,7 @@ Returns:
|
|
- result: The generated UUID.
|
|
- result: The generated UUID.
|
|
*/
|
|
*/
|
|
generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
|
|
generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
|
|
- assert(clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data; no number greater than 16,383.")
|
|
|
|
|
|
+ assert(clock_seq <= 0x3FFF, BIG_CLOCK_ERROR)
|
|
unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100
|
|
unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100
|
|
|
|
|
|
uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals)
|
|
uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals)
|
|
@@ -89,13 +89,15 @@ Returns:
|
|
generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
|
|
generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
|
|
unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100
|
|
unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100
|
|
|
|
|
|
- timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals)
|
|
|
|
|
|
+ uuid_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)
|
|
|
|
|
|
+ result = transmute(Identifier)(
|
|
|
|
+ uuid_timestamp & 0x0FFFFFFF_FFFFF000 << 68 |
|
|
|
|
+ uuid_timestamp & 0x00000000_00000FFF << 64
|
|
|
|
+ )
|
|
|
|
|
|
if realized_clock_seq, ok := clock_seq.?; ok {
|
|
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.")
|
|
|
|
|
|
+ assert(realized_clock_seq <= 0x3FFF, BIG_CLOCK_ERROR)
|
|
result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8)
|
|
result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8)
|
|
result[9] = cast(u8)realized_clock_seq
|
|
result[9] = cast(u8)realized_clock_seq
|
|
} else {
|
|
} else {
|
|
@@ -126,7 +128,7 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, times
|
|
Generate a version 7 UUID.
|
|
Generate a version 7 UUID.
|
|
|
|
|
|
This UUID will be pseudorandom, save for 6 pre-determined version and variant
|
|
This UUID will be pseudorandom, save for 6 pre-determined version and variant
|
|
-bits and a 48 bit timestamp.
|
|
|
|
|
|
+bits and a 48-bit timestamp.
|
|
|
|
|
|
It is designed with time-based sorting in mind, such as for database usage, as
|
|
It is designed with time-based sorting in mind, such as for database usage, as
|
|
the highest bits are allocated from the timestamp of when it is created.
|
|
the highest bits are allocated from the timestamp of when it is created.
|
|
@@ -141,13 +143,11 @@ generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identif
|
|
assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR)
|
|
assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR)
|
|
unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6
|
|
unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6
|
|
|
|
|
|
- temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT
|
|
|
|
|
|
+ result = transmute(Identifier)(cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT)
|
|
|
|
|
|
bytes_generated := rand.read(result[6:])
|
|
bytes_generated := rand.read(result[6:])
|
|
assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.")
|
|
assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.")
|
|
|
|
|
|
- result |= transmute(Identifier)temporary
|
|
|
|
-
|
|
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] |= 0x70
|
|
result[VERSION_BYTE_INDEX] |= 0x70
|
|
|
|
|
|
@@ -161,7 +161,7 @@ generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identif
|
|
Generate a version 7 UUID that has an incremented counter.
|
|
Generate a version 7 UUID that has an incremented counter.
|
|
|
|
|
|
This UUID will be pseudorandom, save for 6 pre-determined version and variant
|
|
This UUID will be pseudorandom, save for 6 pre-determined version and variant
|
|
-bits, a 48 bit timestamp, and 12 bits of counter state.
|
|
|
|
|
|
+bits, a 48-bit timestamp, and 12 bits of counter state.
|
|
|
|
|
|
It is designed with time-based sorting in mind, such as for database usage, as
|
|
It is designed with time-based sorting in mind, such as for database usage, as
|
|
the highest bits are allocated from the timestamp of when it is created.
|
|
the highest bits are allocated from the timestamp of when it is created.
|
|
@@ -183,7 +183,7 @@ Example:
|
|
}
|
|
}
|
|
|
|
|
|
Inputs:
|
|
Inputs:
|
|
-- counter: A 12-bit value, incremented each time a UUID is generated in a batch.
|
|
|
|
|
|
+- counter: A 12-bit value which should be incremented each time a UUID is generated in a batch.
|
|
- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time.
|
|
- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time.
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
@@ -191,17 +191,17 @@ Returns:
|
|
*/
|
|
*/
|
|
generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
|
|
generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
|
|
assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR)
|
|
assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR)
|
|
- assert(counter <= 0x0fff, "This implementation of the version 7 UUID does not support counters in excess of 12 bits (4,095).")
|
|
|
|
|
|
+ assert(counter <= 0x0fff, VERSION_7_BIG_COUNTER_ERROR)
|
|
unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6
|
|
unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6
|
|
|
|
|
|
- temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT
|
|
|
|
- temporary |= cast(u128be)counter << VERSION_7_COUNTER_SHIFT
|
|
|
|
|
|
+ result = transmute(Identifier)(
|
|
|
|
+ cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT |
|
|
|
|
+ cast(u128be)counter << VERSION_7_COUNTER_SHIFT
|
|
|
|
+ )
|
|
|
|
|
|
bytes_generated := rand.read(result[8:])
|
|
bytes_generated := rand.read(result[8:])
|
|
assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.")
|
|
assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.")
|
|
|
|
|
|
- result |= transmute(Identifier)temporary
|
|
|
|
-
|
|
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] |= 0x70
|
|
result[VERSION_BYTE_INDEX] |= 0x70
|
|
|
|
|