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]
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
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โ
| Version | Method | Based On | Best For |
|---|---|---|---|
| UUID1 | uuid.uuid1() | Timestamp + MAC address | Time-ordered IDs |
| UUID4 | uuid.uuid4() | Random | Most common choice |
| UUID5 | uuid.uuid5(namespace, name) | SHA-1 hash of namespace + name | Deterministic 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"
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
- 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โ
| Method | Format | Secure? | 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.