Skip to content

How to Generate Random IDs Using UUID in Python

Learn how to create unique identifiers in Python with the uuid module, covering uuid4() for random IDs, uuid1() for time-ordered IDs, and uuid5() for deterministic UUIDs, along with best practices and security considerations.

Generating unique identifiers is a fundamental requirement in software development, from database primary keys and session tokens to distributed system coordination and file naming. Python's built-in uuid module provides a reliable, standardized way to create Universally Unique Identifiers (UUIDs) as defined by RFC 4122, ensuring that each ID is virtually guaranteed to be unique across time and space.

In this guide, you'll learn how to generate random IDs using different UUID versions, understand their internal structure, and choose the right approach based on your uniqueness, privacy, and security requirements.

What Is a UUID?

A UUID (Universally Unique Identifier) is a 128-bit value formatted as a 32-character hexadecimal string with hyphens:

fbd204a7-318e-4dd3-86e0-e6d524fc3f98

The probability of generating two identical UUIDs is astronomically low: roughly 1 in 5.3 × 10³⁶. This makes them safe to use as unique identifiers without any central coordination.

Python's uuid module supports several UUID versions:

Version Based On Privacy Safe Use Case
uuid1() Timestamp + MAC address ❌ Time-ordered IDs, logging
uuid3() MD5 hash of namespace + name ✅ Deterministic IDs from names
uuid4() Random numbers ✅ General-purpose unique IDs
uuid5() SHA-1 hash of namespace + name ✅ Deterministic IDs (more secure than uuid3)

uuid4() generates a UUID using 122 bits of randomness, with no dependence on hardware or timestamps. This is the most commonly used version and the best default choice:

import uuid

uid = uuid.uuid4()
print("Random UUID:", uid)
print("As string:  ", str(uid))

Output:

Random UUID: 613a4e90-8659-4c22-a22a-2ce344316154
As string:   613a4e90-8659-4c22-a22a-2ce344316154

Why uuid4() Is Usually the Best Choice

  • No privacy leaks: Doesn't expose your MAC address or system time.
  • No coordination needed: Can be generated independently on any machine.
  • Extremely low collision probability: Safe for databases, APIs, and distributed systems.
  • Simple: Just call uuid.uuid4(): no configuration required.

Common Formats

import uuid

uid = uuid.uuid4()

print("Standard:  ", uid)        # With hyphens
print("Hex:       ", uid.hex)    # 32 chars, no hyphens
print("Integer:   ", uid.int)    # 128-bit integer
print("Bytes:     ", uid.bytes)  # 16-byte string
print("URN:       ", uid.urn)    # URN format

Output:

Standard:   622cea47-3525-4dd7-a623-4550b9391fd5
Hex:        622cea4735254dd7a6234550b9391fd5
Integer:    130497556374191884339973281723981570005
Bytes:      b'b,\xeaG5%M\xd7\xa6#EP\xb99\x1f\xd5'
URN:        urn:uuid:622cea47-3525-4dd7-a623-4550b9391fd5

Generating Multiple UUIDs

import uuid

for i in range(5):
    print(f"ID {i + 1}: {uuid.uuid4()}")

Output:

ID 1: 4566732f-8f20-4092-963c-cfc9e6d31067
ID 2: 4363d75e-51e7-484c-a1de-cb1ba8647ea8
ID 3: efa93ee9-f0a9-4b54-aeb1-1df5a12fa6ee
ID 4: 5739980c-b2a1-44d1-b7d4-edb413a877cb
ID 5: cf516b69-de55-4515-ba55-973af60bc387

Method 2: Using uuid1() (Time-Based)

uuid1() generates a UUID using the current timestamp and the machine's MAC address. This guarantees uniqueness and provides time-ordering, but exposes hardware information:

import uuid

uid = uuid.uuid1()
print("UUID1:", uid)

Output:

UUID1: ecc72432-09f3-11f1-ac2f-7aedd2986efe

Exploring UUID1 Components

import uuid

uid = uuid.uuid1()

print("Byte repr:", repr(uid.bytes))
print("Integer:  ", uid.int)
print("Hex:      ", uid.hex)

print("\nVersion:", uid.version)
print("Variant:", uid.variant)

print("\nFields:", uid.fields)
print("Time Low:     ", uid.fields[0])
print("Time Mid:     ", uid.fields[1])
print("Time Hi:      ", uid.fields[2])
print("Clock Seq Hi: ", uid.fields[3])
print("Clock Seq Low:", uid.fields[4])
print("Node (MAC):   ", uid.fields[5])

Output:

Byte repr: b'\xf2I$\x14\t\xf3\x11\xf1\x92 z\xed\xd2\x98n\xfe'
Integer:   322052944405010884204009590938400222974
Hex:       f249241409f311f192207aedd2986efe

Version: 1
Variant: specified in RFC 4122

Fields: (4064879636, 2547, 4593, 146, 32, 135161859043070)
Time Low:      4064879636
Time Mid:      2547
Time Hi:       4593
Clock Seq Hi:  146
Clock Seq Low: 32
Node (MAC):    135161859043070

Method 3: Using uuid3() and uuid5() (Name-Based, Deterministic)

These versions generate deterministic UUIDs from a namespace and a name. The same inputs always produce the same UUID:

import uuid

uid3 = uuid.uuid3(uuid.NAMESPACE_DNS, 'example.com')
print("UUID3:", uid3)

uid5 = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
print("UUID5:", uid5)

uid5_again = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
print("Same? ", uid5 == uid5_again)

Output:

UUID3: 9073926b-929f-31c2-abc9-fad77ae3e8eb
UUID5: cfbff0d1-9375-5685-968c-48ce8b15ae17
Same?  True

Available namespaces include NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID, and NAMESPACE_X500.

Practical Examples

Using UUIDs as Database Keys

import uuid

class User:
    def __init__(self, name, email):
        self.id = str(uuid.uuid4())
        self.name = name
        self.email = email

user = User("Alice", "alice@example.com")
print(f"User ID: {user.id}")
print(f"Name: {user.name}")

Output:

User ID: 85824d32-8776-4b8b-9558-72f55eef1d3c
Name: Alice

Generating Short IDs from UUIDs

Full UUIDs are 36 characters long. If you need shorter IDs, you can truncate or encode them:

import uuid

uid = uuid.uuid4()

short_id = uid.hex[:8]
print(f"Full UUID: {uid}")
print(f"Short ID:  {short_id}")

Output:

Full UUID: d525e374-7b31-43ab-b13a-b30dbea591c0
Short ID:  d525e374

Generating Unique Filenames

import uuid

def generate_filename(extension='txt'):
    return f"{uuid.uuid4().hex[:12]}.{extension}"

print(generate_filename('txt'))
print(generate_filename('png'))
print(generate_filename('csv'))

Output:

bd1d2f0248b4.txt
6d5239bea811.png
4d133acdc7e8.csv

Common Mistake: Using UUIDs for Security Tokens

UUIDs are designed for uniqueness, not security. uuid4() uses Python's random module, which may not be cryptographically secure in all implementations:

import uuid

token = str(uuid.uuid4())

Use the secrets module instead for security-sensitive identifiers:

import secrets

token = secrets.token_hex(16)
print("Secure token:", token)

url_token = secrets.token_urlsafe(16)
print("URL-safe token:", url_token)

Output:

Secure token: 9f8958cd1a5458e87e3d11ee6350f74d
URL-safe token: RXr18jE1GW7yyHZ_yiio4g

Choosing the Right UUID Version

Requirement Recommended Version
General-purpose unique ID uuid4()
Time-ordered ID (non-sensitive) uuid1()
Deterministic ID from a name uuid5() (or uuid3())
Security token / API key Use secrets module instead
Short unique ID uuid4().hex[:N] (with collision risk)

Summary

Python's uuid module provides a simple, reliable way to generate unique identifiers:

  • Use uuid4() as your default: it's random, privacy-safe, and requires no configuration.
  • Use uuid1() when you need time-ordering, but be aware it exposes your MAC address.
  • Use uuid5() when you need deterministic IDs that are always the same for the same input.
  • Never use UUIDs as security tokens: use the secrets module for cryptographic purposes.
  • Access different representations with .hex, .int, .bytes, or str() depending on your storage or transmission needs.
Navigation