Generate random strings in Python

Build random strings from an explicit alphabet, choose secrets for tokens, and distinguish token length, byte count, and uniqueness.

Best practices
Python programming and application logging

For test data, join values drawn from an explicit alphabet with random.choices(). For passwords or authentication tokens, use secrets, which draws from the operating system's secure random source.

Generate letters and digits

import random
import string

def random_string(length):
    if length < 0:
        raise ValueError("Length must be nonnegative")
    alphabet = string.ascii_uppercase + string.digits
    return "".join(random.choices(alphabet, k=length))

print(random_string(10))

The argument should be an integer. A length of zero produces an empty string. This helper is suitable for fixtures and non-secret labels, not credentials.

Choose the alphabet

Constant Characters
string.ascii_uppercase A–Z
string.ascii_lowercase a–z
string.ascii_letters Both ASCII letter cases
string.digits 0–9
string.hexdigits Digits plus a–f and A–F
string.punctuation ASCII punctuation characters

You can combine sets, such as string.ascii_letters + string.digits + "!@#". Avoid accidental duplicate characters if each symbol should have equal probability. For human-readable codes, a custom alphabet such as ABCDEFGHJKLMNPQRSTUVWXYZ23456789 avoids several easily confused symbols.

Generate a secret

import secrets
import string

def secure_token(length):
    if length < 1:
        raise ValueError("Token length must be positive")
    alphabet = string.ascii_letters + string.digits
    return "".join(secrets.choice(alphabet) for _ in range(length))

print(secure_token(32))

The caller must choose a length appropriate to the security requirement; positive length alone is not a security policy. For a URL-safe token without a custom alphabet, use secrets.token_urlsafe(32). Its argument is the number of random bytes, not the output's character count.

Other representations

import secrets
import uuid

identifier = str(uuid.uuid4())
compact_identifier = uuid.uuid4().hex  # 32 hexadecimal characters
hex_token = secrets.token_hex(16)     # 16 random bytes, 32 hex characters

UUIDs are identifiers, not a general replacement for a purpose-built authentication token. Random generation also does not guarantee uniqueness; enforce uniqueness and retry if a database key must never collide.

FAQ

How do I require at least one digit? For a secure token with an alphabet containing digits, repeatedly generate a candidate using secrets and accept it only if any(char.isdigit() for char in candidate) is true. Validate length and alphabet first so the condition is achievable. Do not reintroduce random.shuffle into a security-sensitive construction.

Why not seed random for tokens? Ordinary random is deterministic and designed for simulation rather than secrets. Reproducibility is useful in tests and harmful when an attacker must not predict the next value.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting