package core:encoding/uuid
Overview
package uuid implements Universally Unique Identifiers according to the standard originally outlined in RFC 4122 with additions from RFC 9562.
The UUIDs are textually represented and read in the following string format:
00000000-0000-v000-V000-000000000000
v
is where the version bits reside, and V
is where the variant bits reside.
The meaning of the other bits is version-dependent.
Outside of string representations, UUIDs are represented in memory by a 128-bit structure organized as an array of 16 bytes.
Of the UUID versions which may make use of random number generation, a requirement is placed upon them that the underlying generator be cryptographically-secure, per RFC 9562's suggestion.
Version 1 without a node argument. Version 4 in all cases. Version 6 without either a clock or node argument. Version 7 in all cases.
Example:
package main
import "core:crypto"
import "core:encoding/uuid"
main :: proc() {
my_uuid: uuid.Identifier
{
// This scope will have a CSPRNG.
context.random_generator = crypto.random_generator()
my_uuid = uuid.generate_v7()
}
// Back to the default random number generator.
}
For more information on the specifications, see here: https://www.rfc-editor.org/rfc/rfc4122.html https://www.rfc-editor.org/rfc/rfc9562.html
Index
Types (3)
Variables (4)
Procedures (26)
- clock_seq
- counter_v7
- generate_v1
- generate_v4
- generate_v6
- generate_v7_basic
- generate_v7_with_counter
- generate_v8_hash_bytes
- generate_v8_hash_string
- node
- raw_time_v1
- raw_time_v6
- raw_time_v7
- read
- stamp_v8_array
- stamp_v8_int
- stamp_v8_slice
- time_v1
- time_v6
- time_v7
- to_string_allocated
- to_string_buffer
- unsafe_write
- variant
- version
- write
Procedure Groups (4)
Types
Identifier ¶
Identifier :: distinct [16]u8
A RFC 4122 Universally Unique Identifier
Related Procedures With Parameters
- clock_seq
- counter_v7
- generate_v8_hash_bytes
- generate_v8_hash_string
- node
- raw_time_v1
- raw_time_v6
- raw_time_v7
- time_v1
- time_v6
- time_v7
- to_string_allocated
- to_string_buffer
- unsafe_write
- variant
- version
- write
- generate_v8_hash (procedure groups)
- to_string (procedure groups)
Related Procedures With Returns
- generate_v1
- generate_v4
- generate_v6
- generate_v7_basic
- generate_v7_with_counter
- read
- stamp_v8_array
- stamp_v8_int
- stamp_v8_slice
- generate_v7 (procedure groups)
- stamp_v8 (procedure groups)
Read_Error ¶
Read_Error :: enum int { None, Invalid_Length, Invalid_Hexadecimal, Invalid_Separator, }
Related Procedures With Returns
Variant_Type ¶
Variant_Type :: enum int { Unknown, Reserved_Apollo_NCS, // 0b0xx RFC_4122, // 0b10x Reserved_Microsoft_COM, // 0b110 Reserved_Future, // 0b111 }
Related Procedures With Returns
Constants
EXPECTED_LENGTH ¶
EXPECTED_LENGTH :: 8 + 4 + 4 + 4 + 12 + 4
HNS_INTERVALS_BETWEEN_GREG_AND_UNIX ¶
HNS_INTERVALS_BETWEEN_GREG_AND_UNIX :: 141427 * 24 * 60 * 60 * 1000 * 1000 * 10
The number of 100-nanosecond intervals between 1582-10-15 and 1970-01-01.
VARIANT_BYTE_INDEX ¶
VARIANT_BYTE_INDEX :: 8
VERSION_7_COUNTER_MASK ¶
VERSION_7_COUNTER_MASK :: 0x00000000_00000fff_00000000_00000000
VERSION_7_COUNTER_SHIFT ¶
VERSION_7_COUNTER_SHIFT :: 64
VERSION_7_TIME_MASK ¶
VERSION_7_TIME_MASK :: 0xffffffff_ffff0000_00000000_00000000
VERSION_7_TIME_SHIFT ¶
VERSION_7_TIME_SHIFT :: 80
VERSION_BYTE_INDEX ¶
VERSION_BYTE_INDEX :: 6
Variables
Namespace_DNS ¶
@(rodata) Namespace_DNS: Identifier = …
Name string is a fully-qualified domain name.
Namespace_X500 ¶
@(rodata) Namespace_X500: Identifier = …
Name string is an X.500 DN (in DER or a text output format).
Procedures
clock_seq ¶
clock_seq :: proc "contextless" (id: Identifier) -> (clock_seq: u16) {…}
Get the clock sequence of a version 1 or version 6 UUID.
Inputs:
id: The identifier.
Returns:
clock_seq: The 14-bit clock sequence field.
counter_v7 ¶
counter_v7 :: proc "contextless" (id: Identifier) -> (counter: u16) {…}
Get the 12-bit counter value of a version 7 UUID.
The UUID must have been generated with a counter, otherwise this procedure will return random bits.
Inputs:
id: The identifier.
Returns:
counter: The 12-bit counter value.
generate_v1 ¶
generate_v1 :: proc(clock_seq: u16, node: runtime.Maybe($T=[6]u8) = nil, timestamp: runtime.Maybe($T=Time) = nil) -> (result: Identifier) {…}
Generate a version 1 UUID.
Inputs:
clock_seq: The clock sequence, a number which must be initialized to a random number once in the lifetime of a system.
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.
timestamp: A timestamp from the core:time
package, or nil
to use the current time.
Returns:
result: The generated UUID.
generate_v4 ¶
generate_v4 :: proc() -> (result: Identifier) {…}
Generate a version 4 UUID.
This UUID will be pseudorandom, save for 6 pre-determined version and variant bits.
Returns:
result: The generated UUID.
generate_v6 ¶
generate_v6 :: proc(clock_seq: runtime.Maybe($T=u16) = nil, node: runtime.Maybe($T=[6]u8) = nil, timestamp: runtime.Maybe($T=Time) = nil) -> (result: Identifier) {…}
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.
timestamp: A timestamp from the core:time
package, or nil
to use the current time.
Returns:
result: The generated UUID.
generate_v7_basic ¶
generate_v7_basic :: proc(timestamp: runtime.Maybe($T=Time) = nil) -> (result: Identifier) {…}
Generate a version 7 UUID.
This UUID will be pseudorandom, save for 6 pre-determined version and variant bits and a 48-bit timestamp.
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.
Inputs:
timestamp: A timestamp from the core:time
package, or nil
to use the current time.
Returns:
result: The generated UUID.
generate_v7_with_counter ¶
generate_v7_with_counter :: proc(counter: u16, timestamp: runtime.Maybe($T=Time) = nil) -> (result: Identifier) {…}
Generate a version 7 UUID that has an incremented counter.
This UUID will be pseudorandom, save for 6 pre-determined version and variant 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 the highest bits are allocated from the timestamp of when it is created.
This procedure is preferable if you are generating hundreds or thousands of
UUIDs as a batch within the span of a millisecond. Do note that the counter
only has 12 bits of state, thus counter
cannot exceed the number 4,095.
Example:
import "core:uuid"
// Create a batch of UUIDs all at once.
batch: [dynamic]uuid.Identifier
for i: u16 = 0; i < 1000; i += 1 {
my_uuid := uuid.generate_v7_counter(i)
append(&batch, my_uuid)
}
Inputs:
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.
Returns:
result: The generated UUID.
generate_v8_hash_bytes ¶
generate_v8_hash_bytes :: proc(namespace: Identifier, name: []u8, algorithm: crypto_hash.Algorithm) -> (result: Identifier) {…}
Generate a version 8 UUID using a specific hashing algorithm.
This UUID is generated by hashing a name with a namespace.
Note that all version 8 UUIDs are for experimental or vendor-specific use cases, per the specification. This use case in particular is for offering a non-legacy alternative to UUID versions 3 and 5.
Inputs:
namespace: An 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 which will be hashed with the namespace.
algorithm: A hashing algorithm from core:crypto/hash
.
Returns:
result: The generated UUID.
Example:
import "core:crypto/hash"
import "core:encoding/uuid"
import "core:fmt"
main :: proc() {
my_uuid := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.odin-lang.org", .SHA256)
my_uuid_string := uuid.to_string(my_uuid, context.temp_allocator)
fmt.println(my_uuid_string)
}
3730f688-4bff-8dce-9cbf-74a3960c5703
generate_v8_hash_string ¶
generate_v8_hash_string :: proc(namespace: Identifier, name: string, algorithm: crypto_hash.Algorithm) -> (result: Identifier) {…}
Generate a version 8 UUID using a specific hashing algorithm.
This UUID is generated by hashing a name with a namespace.
Note that all version 8 UUIDs are for experimental or vendor-specific use cases, per the specification. This use case in particular is for offering a non-legacy alternative to UUID versions 3 and 5.
Inputs:
namespace: An 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 which will be hashed with the namespace.
algorithm: A hashing algorithm from core:crypto/hash
.
Returns:
result: The generated UUID.
Example:
import "core:crypto/hash"
import "core:encoding/uuid"
import "core:fmt"
main :: proc() {
my_uuid := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.odin-lang.org", .SHA256)
my_uuid_string := uuid.to_string(my_uuid, context.temp_allocator)
fmt.println(my_uuid_string)
}
3730f688-4bff-8dce-9cbf-74a3960c5703
node ¶
node :: proc "contextless" (id: Identifier) -> (node: [6]u8) {…}
Get the node of a version 1 or version 6 UUID.
Inputs:
id: The identifier.
Returns:
node: The 48-bit spatially unique identifier.
raw_time_v1 ¶
raw_time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) {…}
Get the raw timestamp of a version 1 UUID.
Inputs:
id: The identifier.
Returns:
timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15.
raw_time_v6 ¶
raw_time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: u64) {…}
Get the raw timestamp of a version 6 UUID.
Inputs:
id: The identifier.
Returns:
timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15.
raw_time_v7 ¶
raw_time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: u64) {…}
Get the raw timestamp of a version 7 UUID.
Inputs:
id: The identifier.
Returns:
timestamp: The timestamp, in milliseconds since the UNIX epoch.
read ¶
read :: proc "contextless" (str: string) -> (id: Identifier, error: Read_Error) {…}
Convert a string to a UUID.
Inputs:
str: A string in the 8-4-4-4-12 format.
Returns:
id: The converted identifier, or nil
if there is an error.
error: A description of the error, or nil
if successful.
stamp_v8_array ¶
stamp_v8_array :: proc(array: [16]u8) -> (result: Identifier) {…}
Stamp an array of 16 bytes as being a valid version 8 UUID.
Per the specification, all version 8 UUIDs are either for experimental or vendor-specific purposes. This procedure allows for converting arbitrary data into custom UUIDs.
Inputs:
array: An array of 16 bytes.
Returns:
result: A valid version 8 UUID.
stamp_v8_int ¶
stamp_v8_int :: proc(#any_int integer: u128) -> (result: Identifier) {…}
Stamp a 128-bit integer as being a valid version 8 UUID.
Per the specification, all version 8 UUIDs are either for experimental or vendor-specific purposes. This procedure allows for converting arbitrary data into custom UUIDs.
Inputs:
integer: Any integer type.
Returns:
result: A valid version 8 UUID.
stamp_v8_slice ¶
stamp_v8_slice :: proc(slice: []u8) -> (result: Identifier) {…}
Stamp a slice of bytes as being a valid version 8 UUID.
If the slice is less than 16 bytes long, the data available will be used. If it is longer than 16 bytes, only the first 16 will be used.
This procedure does not modify the underlying slice.
Per the specification, all version 8 UUIDs are either for experimental or vendor-specific purposes. This procedure allows for converting arbitrary data into custom UUIDs.
Inputs:
slice: A slice of bytes.
Returns:
result: A valid version 8 UUID.
time_v1 ¶
time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) {…}
Get the timestamp of a version 1 UUID.
Inputs:
id: The identifier.
Returns:
timestamp: The timestamp of the UUID.
time_v6 ¶
time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) {…}
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_v7 ¶
time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) {…}
Get the timestamp of a version 7 UUID.
Inputs:
id: The identifier.
Returns:
timestamp: The timestamp, in milliseconds since the UNIX epoch.
to_string_allocated ¶
to_string_allocated :: proc(id: Identifier, allocator := context.allocator, loc := #caller_location) -> (str: string, error: runtime.Allocator_Error) #optional_ok {…}
Convert a UUID to a string in the 8-4-4-4-12 format.
Allocates Using Provided Allocator
Inputs:
id: The identifier to convert.
allocator: (default: context.allocator)
loc: The caller location for debugging purposes (default: #caller_location)
Returns:
str: The allocated and converted string.
error: An optional allocator error if one occured, nil
otherwise.
to_string_buffer ¶
to_string_buffer :: proc(id: Identifier, buffer: []u8, loc := #caller_location) -> (str: string) {…}
Convert a UUID to a string in the 8-4-4-4-12 format.
Inputs:
id: The identifier to convert.
buffer: A byte buffer to store the result. Must be at least 36 bytes large.
loc: The caller location for debugging purposes (default: #caller_location)
Returns:
str: The converted string which will be stored in buffer
.
unsafe_write ¶
unsafe_write :: proc(w: io.Stream, id: Identifier) {…}
Write a UUID in the 8-4-4-4-12 format.
This procedure performs no error checking on the underlying stream.
Inputs:
w: A writable stream.
id: The identifier to convert.
variant ¶
variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) {…}
Get the variant of a UUID.
Inputs:
id: The identifier.
Returns:
variant: The variant type.
version ¶
version :: proc "contextless" (id: Identifier) -> (number: int) {…}
Get the version of a UUID.
Inputs:
id: The identifier.
Returns:
number: The version number.
write ¶
write :: proc(w: io.Stream, id: Identifier) -> (error: io.Error) {…}
Write a UUID in the 8-4-4-4-12 format.
This procedure performs error checking with every byte written.
If you can guarantee beforehand that your stream has enough space to hold the
UUID (36 bytes), then it is better to use unsafe_write
instead as that will
be faster.
Inputs:
w: A writable stream.
id: The identifier to convert.
Returns:
error: An io
error, if one occurred, otherwise nil
.
Procedure Groups
generate_v7 ¶
generate_v7 :: proc{ generate_v7_basic, generate_v7_with_counter, }
generate_v8_hash ¶
generate_v8_hash :: proc{ generate_v8_hash_bytes, generate_v8_hash_string, }
stamp_v8 ¶
stamp_v8 :: proc{ stamp_v8_int, stamp_v8_array, stamp_v8_slice, }
to_string ¶
to_string :: proc{ to_string_allocated, to_string_buffer, }
Source Files
Generation Information
Generated with odin version dev-2024-09 (vendor "odin") Windows_amd64 @ 2024-09-07 21:12:27.306589400 +0000 UTC