Skip to main content

How to Generate Random IDs in Python

Generating random IDs is a common requirement in software development, whether you need unique identifiers for user accounts, session tokens, database records, order numbers, or API keys. Python offers several built-in modules to generate random IDs, each suited for different use cases and security requirements.

This guide covers multiple approaches, from simple numeric IDs to cryptographically secure tokens and globally unique identifiers.

Using random.randint() for Simple Numeric IDsโ€‹

The random module provides randint() for generating random integers within a specified range. This is the simplest approach for creating basic numeric IDs.

import random

# Generate a single random ID between 1 and 10000
single_id = random.randint(1, 10000)
print("Single ID:", single_id)

# Generate 5 random IDs
ids = [random.randint(1, 10000) for _ in range(5)]
print("Multiple IDs:", ids)

Output (varies each run):

Single ID: 9692
Multiple IDs: [1099, 1944, 2818, 8951, 3924]
Not suitable for security-sensitive applications

The random module uses a pseudo-random number generator (PRNG) that is not cryptographically secure. Its output can be predicted if the seed is known. Never use random for:

  • Session tokens or authentication
  • Password generation
  • Any security-critical identifiers

Use the secrets module instead for these cases.

Generating Unique Numeric IDsโ€‹

Since random.randint() can produce duplicate values, use random.sample() if you need guaranteed uniqueness:

import random

# Generate 10 unique IDs from range 1โ€“1000
unique_ids = random.sample(range(1, 1001), 10)
print("Unique IDs:", unique_ids)

Output:

Unique IDs: [95, 231, 325, 723, 647, 302, 989, 915, 60, 509]

random.sample() draws without replacement, guaranteeing no duplicates in the result.

Using uuid for Globally Unique IDsโ€‹

The uuid module generates Universally Unique Identifiers (UUIDs), which are 128-bit values that are virtually guaranteed to be unique across all systems and all time. UUIDs are the standard choice for distributed systems, database primary keys, and any scenario where IDs must be unique without coordination.

UUID Version 4 (Random)โ€‹

uuid4() generates a completely random UUID:

import uuid

# Generate a single UUID
unique_id = uuid.uuid4()
print("UUID:", unique_id)
print("Type:", type(unique_id))
print("As string:", str(unique_id))

Output:

UUID: 81106ba0-e90e-4621-b7e1-d2717a55e343
Type: <class 'uuid.UUID'>
As string: 81106ba0-e90e-4621-b7e1-d2717a55e343

Generating Multiple UUIDsโ€‹

import uuid

ids = [str(uuid.uuid4()) for _ in range(3)]
for i, uid in enumerate(ids, 1):
print(f"ID {i}: {uid}")

Output:

ID 1: 8823db61-fab7-4797-8fab-4b7d3ea5e856
ID 2: 05ca75ff-611e-4049-b811-ebf71886eb0c
ID 3: dfe45e0b-3935-44e0-b029-686d2c4bd190

Shorter UUID Formatsโ€‹

Full UUIDs are 36 characters long. If you need shorter IDs, you can extract portions or remove hyphens:

import uuid

full_uuid = uuid.uuid4()

# Remove hyphens (32 characters)
compact = full_uuid.hex
print("Compact:", compact)

# First 8 characters only
short_id = full_uuid.hex[:8]
print("Short ID:", short_id)

Output:

Compact: 988d362862cf428da6df0d2499949a5e
Short ID: 988d3628
note

Shortening a UUID reduces its uniqueness guarantee. An 8-character hex string has about 4 billion possible values, which is sufficient for many applications but not for large-scale distributed systems.

UUID Versions Comparisonโ€‹

VersionMethodBased OnBest For
UUID1uuid.uuid1()Timestamp + MAC addressTime-ordered IDs
UUID4uuid.uuid4()RandomMost common choice
UUID5uuid.uuid5(namespace, name)SHA-1 hash of namespace + nameDeterministic IDs from names

Using secrets for Cryptographically Secure IDsโ€‹

The secrets module (Python 3.6+) is designed specifically for generating cryptographically strong random values. Use it whenever security matters.

Secure Random Integersโ€‹

import secrets

# Generate a secure random integer between 1 and 10000
secure_id = secrets.randbelow(10000) + 1
print("Secure ID:", secure_id)

Output:

Secure ID: 4756

Secure Token Stringsโ€‹

secrets.token_hex() and secrets.token_urlsafe() generate random strings ideal for API keys, session tokens, and password reset links:

import secrets

# Hexadecimal token (32 hex characters = 16 bytes)
hex_token = secrets.token_hex(16)
print("Hex token:", hex_token)

# URL-safe token (great for URLs and APIs)
url_token = secrets.token_urlsafe(16)
print("URL-safe token:", url_token)

# Raw bytes token
bytes_token = secrets.token_bytes(16)
print("Bytes token:", bytes_token)

Output:

Hex token: 1d15f826c2d3861efa1c6e13a936b318
URL-safe token: P7Aju-MT2tMG2_s1p48kXg
Bytes token: b"\xf8\x19\x04gBP't6\xb5\xa9W\x97\xb8\x88\xfe"
How many bytes do you need?

The nbytes parameter determines the strength of the token:

  • 16 bytes (128 bits): sufficient for most applications.
  • 32 bytes (256 bits): recommended for high-security tokens.
# High-security token
strong_token = secrets.token_urlsafe(32)
print("Strong token:", strong_token)

Using string + random for Custom Format IDsโ€‹

For IDs with a specific format (for example, alphanumeric, specific length, or with a prefix), combine the string and random (or secrets) modules:

import string
import secrets

def generate_id(length=12, prefix=""):
"""Generate a custom random alphanumeric ID."""
alphabet = string.ascii_uppercase + string.digits
random_part = ''.join(secrets.choice(alphabet) for _ in range(length))
return f"{prefix}{random_part}"

# Simple alphanumeric ID
print("ID:", generate_id())

# With prefix
print("Order:", generate_id(length=8, prefix="ORD-"))
print("User:", generate_id(length=6, prefix="USR-"))

# Generate multiple
ids = [generate_id(length=10, prefix="TXN-") for _ in range(3)]
for txn_id in ids:
print(f"Transaction: {txn_id}")

Output:

ID: QSCG9WC4OM13
Order: ORD-REMW9V9G
User: USR-6OYAHW
Transaction: TXN-9QX427B37Q
Transaction: TXN-WVA1JM3SFK
Transaction: TXN-MNLNW5BSG6

Ensuring Uniquenessโ€‹

None of the random generation methods guarantee uniqueness (except random.sample() from a fixed range). For production systems, use the following strategies to ensure unique IDs:

import uuid

def generate_unique_ids(count):
"""Generate guaranteed unique IDs using a set."""
ids = set()
while len(ids) < count:
ids.add(str(uuid.uuid4()))
return list(ids)

unique_ids = generate_unique_ids(5)
for uid in unique_ids:
print(uid)

Output:

eafaaa15-062d-4035-85c6-2fa1dcf5a20c
2673dbc5-8727-4552-ae0a-959100f569e1
593f2599-c674-4887-bbb7-d64cae3a3db9
1e47cb30-923e-47aa-8f45-dd200ba29392
a077fe4a-88c0-493c-95d9-d118ffc03944
Best practices for unique IDs in production
  • Database-backed uniqueness: use auto-incrementing primary keys or unique constraints.
  • UUIDs: the probability of collision with uuid4() is astronomically low (1 in 2ยนยฒยฒ possibilities).
  • Timestamps + random: combine a timestamp with random data for time-ordered unique IDs.

Choosing the Right Methodโ€‹

MethodFormatSecure?Unique?Best For
random.randint()IntegerโŒโŒQuick prototyping, games
random.sample()IntegerโŒโœ… (in range)Unique numbers from a pool
uuid.uuid4()UUID stringโœ…โœ… (virtually)Database keys, distributed systems
secrets.token_hex()Hex stringโœ…โœ… (virtually)API keys, session tokens
secrets.token_urlsafe()Base64 stringโœ…โœ… (virtually)URLs, password reset links
Custom with secrets.choice()Any formatโœ…โŒFormatted IDs with prefixes

Conclusionโ€‹

Python provides excellent built-in tools for generating random IDs across all security levels.

  • For simple, non-sensitive use cases, random.randint() gets the job done quickly.
  • For production applications requiring globally unique identifiers, uuid.uuid4() is the standard choice.

When security is critical, such as session tokens, API keys, or password reset links, always use the secrets module. Choose the method that matches your uniqueness requirements, format needs, and security level.