package core:encoding/uuid

⌘K
Ctrl+K
or
/

    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

    Types

    Identifier ¶

    Identifier :: distinct [16]u8
     

    A RFC 4122 Universally Unique Identifier

    Related Procedures With Parameters
    Related Procedures With Returns

    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_OID ¶

    @(rodata)
    Namespace_OID: Identifier = …
     

    Name string is an ISO OID.

    Namespace_URL ¶

    @(rodata)
    Namespace_URL: Identifier = …
     

    Name string is a URL.

    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)
    }
    
    Output:
    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)
    }
    
    Output:
    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

    Source Files

    Generation Information

    Generated with odin version dev-2024-09 (vendor "odin") Windows_amd64 @ 2024-09-07 21:12:27.306589400 +0000 UTC