Skip to content

UUID Module

The UUID (Universally Unique Identifier) module provides comprehensive support for generating, parsing, and manipulating UUIDs according to RFC 4122 and newer specifications. It supports all major UUID versions (v1-v7) with comprehensive error handling and validation.

Quick Start

UUID Quick Start
package main
import uuid
import fmt

// Generate a random UUID v4
var my_uuid, err = uuid.v4()
if err != None {
    fmt.Println("Error generating UUID:", err)
} else {
    var uuid_string, toString_err = uuid.toString(my_uuid)
    if toString_err != None {
        fmt.Println("Error converting to string:", toString_err)
    } else {
        fmt.Println("Generated UUID:", uuid_string)
    }
}

UUID Versions

The UUID module supports all standard UUID versions:

Version Type Description Use Cases
v1 Time-based Uses timestamp and MAC address Legacy systems, node identification
v2 DCE Security Uses timestamp, MAC, and local domain DCE environments (rare)
v3 Name-based (MD5) Deterministic based on namespace and name Legacy deterministic IDs
v4 Random Cryptographically secure random General purpose, database keys
v5 Name-based (SHA-1) Deterministic based on namespace and name Deterministic IDs (preferred over v3)
v6 Reordered time Time-based with better sorting Database-friendly time-based IDs
v7 Time-ordered Unix timestamp with random suffix Time-series data, events

Core Functions

UUID Generation

uuid.v4() -> (UUID, error)

Generates a cryptographically secure random UUID v4.

Generate UUID v4
1
2
3
4
5
6
7
8
9
var my_uuid, err = uuid.v4()
if err != None {
    fmt.Println("Error:", err)
} else {
    var uuid_string, toString_err = uuid.toString(my_uuid)
    if toString_err == None {
        fmt.Println("UUID:", uuid_string)
    }
}

uuid.v1() -> (UUID, error)

Generates a time-based UUID v1 using current timestamp and system MAC address.

Generate UUID v1
1
2
3
4
5
6
var time_uuid, err = uuid.v1()
if err != None {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Generated time-based UUID")
}

uuid.v7() -> (UUID, error)

Generates a time-ordered UUID v7 using Unix timestamp in milliseconds.

Generate UUID v7
1
2
3
4
5
6
var time_ordered_uuid, err = uuid.v7()
if err != None {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Generated time-ordered UUID (naturally sortable)")
}

UUID Parsing and Validation

uuid.parse(s string) -> (UUID, error)

Parses a UUID string in standard format.

Parse UUID
1
2
3
4
5
6
var parsed_uuid, err = uuid.parse("550e8400-e29b-41d4-a716-446655440000")
if err != None {
    fmt.Println("Parse error:", err)
} else {
    fmt.Println("Successfully parsed UUID")
}

uuid.validate(s string) -> (bool, error)

Validates if a string is a properly formatted UUID.

Validate UUID
1
2
3
4
5
6
7
8
var is_valid, err = uuid.validate("550e8400-e29b-41d4-a716-446655440000")
if err != None {
    fmt.Println("Validation error:", err)
} else {
    if is_valid {
        fmt.Println("Valid UUID format")
    }
}

UUID Information

uuid.version(u UUID) -> (int, error)

Returns the version number of the UUID (1-7).

Get UUID Version
1
2
3
4
5
6
var version, err = uuid.version(my_uuid)
if err != None {
    fmt.Println("Version error:", err)
} else {
    fmt.Println("UUID version:", version)
}

uuid.variant(u UUID) -> (int, error)

Returns the variant of the UUID (should be 1 for RFC 4122 UUIDs).

uuid.isNil(u UUID) -> (bool, error)

Checks if the UUID is the nil UUID (all zeros).

UUID Conversion

uuid.toString(u UUID) -> (string, error)

Converts UUID to lowercase string format.

Convert to String
1
2
3
4
5
6
var uuid_string, err = uuid.toString(my_uuid)
if err != None {
    fmt.Println("toString error:", err)
} else {
    fmt.Println("UUID:", uuid_string)
}

uuid.toStringUpper(u UUID) -> (string, error)

Converts UUID to uppercase string format.

uuid.toBytes(u UUID) -> (string, error)

Converts UUID to 16-byte binary representation.

uuid.fromBytes(bytes string) -> (UUID, error)

Creates UUID from 16-byte binary data.

Name-based UUIDs

Predefined Namespaces

The module provides RFC 4122 standard namespaces:

  • uuid.namespaceDNS() - For domain names
  • uuid.namespaceURL() - For URLs
  • uuid.namespaceOID() - For ISO OIDs
  • uuid.namespaceX500() - For X.500 DNs

Example: Deterministic UUIDs

Deterministic UUIDs
package main
import uuid
import fmt

// Create deterministic UUIDs from domain names
var dns_namespace, ns_err = uuid.namespaceDNS()
if ns_err != None {
    fmt.Println("Error getting DNS namespace:", ns_err)
} else {
    var domain_uuid, uuid_err = uuid.v5(dns_namespace, "example.com")
    if uuid_err != None {
        fmt.Println("Error generating UUID:", uuid_err)
    } else {
        var uuid_string, toString_err = uuid.toString(domain_uuid)
        if toString_err == None {
            fmt.Println("Domain UUID:", uuid_string)

            // Generate same UUID again to show determinism
            var same_uuid, same_err = uuid.v5(dns_namespace, "example.com")
            if same_err == None {
                var same_string, same_toString_err = uuid.toString(same_uuid)
                if same_toString_err == None {
                    fmt.Println("Same UUID:", same_string)
                    fmt.Println("Deterministic:", uuid_string == same_string)
                }
            }
        }
    }
}

Time-series UUIDs

UUID v7 is perfect for time-series data as it's naturally sortable by generation time:

Time-Series UUIDs
package main
import uuid
import fmt

// Generate time-ordered UUIDs for events
var events = ["UserLogin", "PageView", "Purchase", "Logout"]

for var i = 0; i < len(events); i = i + 1 {
    var event_type = events[i]

    var event_id, event_err = uuid.v7()
    if event_err != None {
        fmt.Println("Error generating event ID:", event_err)
    } else {
        var event_string, toString_err = uuid.toString(event_id)
        if toString_err != None {
            fmt.Println("Error converting to string:", toString_err)
        } else {
            fmt.Println("Event:", event_type, "ID:", event_string)

            // Extract timestamp
            var timestamp, timestamp_err = uuid.getV7Timestamp(event_id)
            if timestamp_err == None {
                fmt.Println("  Timestamp:", timestamp, "ms")
            }
        }
    }
}

Special UUIDs

Nil UUID

Nil UUID
var nil_uuid, err = uuid.nil()
if err != None {
    fmt.Println("Error:", err)
} else {
    var nil_string, toString_err = uuid.toString(nil_uuid)
    if toString_err == None {
        fmt.Println("Nil UUID:", nil_string)
        // Output: 00000000-0000-0000-0000-000000000000
    }
}

Error Handling

All UUID functions return tuples (result, error). Always check for errors:

Error Handling
// Good: Always check for errors
var my_uuid, err = uuid.v4()
if err != None {
    fmt.Println("Error generating UUID:", err)
} else {
    // Use my_uuid safely
    var uuid_string, toString_err = uuid.toString(my_uuid)
    if toString_err == None {
        fmt.Println("Generated UUID:", uuid_string)
    }
}

Best Practices

Version Selection

  1. Use v4 for general-purpose unique identifiers
  2. Database primary keys
  3. Session tokens
  4. File identifiers

  5. Use v7 for time-series data

  6. Event IDs
  7. Log entries
  8. Message queue IDs

  9. Use v5 for deterministic identifiers

  10. Cache keys
  11. Content-based IDs
  12. Reproducible identifiers

  13. Use v6 for distributed systems

  14. Node-aware identifiers
  15. Database-friendly time-based IDs

Security Considerations

  • Use v4 UUIDs for session tokens (unpredictable)
  • Don't expose internal UUIDs in public APIs
  • Be careful with name-based UUIDs (predictable from input)

Performance Tips

  • Cache parsed UUIDs to avoid repeated parsing
  • Use binary UUID representation in databases (16 bytes vs 36 characters)
  • Choose appropriate UUID version for your indexing needs
  • Use v7 UUIDs for time-based queries (natural ordering)

Testing

The UUID module includes comprehensive tests:

1
2
3
4
5
6
7
# Run UUID tests
just test_uuid

# Run individual tests
./harneet examples/uuid/uuid_basic_test.ha
./harneet examples/uuid/uuid_simple_test.ha
./harneet examples/uuid/uuid_all_versions_test.ha

Complete Example

Complete UUID Example
package main
import uuid
import fmt

fmt.Println("=== UUID Module Demo ===")

// Generate different UUID versions
var v1_uuid, v1_err = uuid.v1()
var v4_uuid, v4_err = uuid.v4()
var v7_uuid, v7_err = uuid.v7()

if v1_err == None && v4_err == None && v7_err == None {
    var v1_string, v1_str_err = uuid.toString(v1_uuid)
    var v4_string, v4_str_err = uuid.toString(v4_uuid)
    var v7_string, v7_str_err = uuid.toString(v7_uuid)

    if v1_str_err == None && v4_str_err == None && v7_str_err == None {
        fmt.Println("UUID v1 (time-based):", v1_string)
        fmt.Println("UUID v4 (random):", v4_string)
        fmt.Println("UUID v7 (time-ordered):", v7_string)

        // Show versions
        var v1_version, v1_version_err = uuid.version(v1_uuid)
        var v4_version, v4_version_err = uuid.version(v4_uuid)
        var v7_version, v7_version_err = uuid.version(v7_uuid)

        if v1_version_err == None && v4_version_err == None && v7_version_err == None {
            fmt.Println("Versions:", v1_version, v4_version, v7_version)
        }
    }
}

fmt.Println("=== Demo complete ===")

References


For more detailed API reference and advanced examples, see the complete UUID documentation in the documents/ directory.