Random Numbers & Cryptographic Secrets
Generate reproducible test distributions with random and produce secure tokens with the secrets module.
PRNGs vs CSPRNGs: When to Use random vs secrets
Python ships two standard library modules for randomness, with completely different threat models. random uses the Mersenne Twister PRNG — fast, seedable, and reproducible, but predictable after observing 624 consecutive outputs. secrets sources entropy directly from the OS CSPRNG, cannot be seeded, and is safe for security-sensitive values.
Security Invariant: never use random for passwords, API keys, session tokens, or encryption material — reach for secrets instead.
random is rolling plastic dice for a board game; secrets is drawing a cryptographic key inside a fortified bank vault.
Contrasting PRNG Output with Cryptographic Tokens
Run the snippet below to contrast a deterministic simulation roll against a cryptographically secure token:
import random
import secrets
# 1. Non-cryptographic simulation (random)
random.seed(42)
roll = random.randint(1, 6)
print("Deterministic dice roll (seed=42):", roll)
# 2. Cryptographically secure token (secrets)
api_token = secrets.token_hex(16) # 32 hex characters
session_id = secrets.token_urlsafe(24) # URL-safe Base64 token
print("Secure API Token:", api_token)
print("Secure Session ID:", session_id)Initializes the PRNG deterministically for reproducible tests and simulations.
Select with replacement and weights, or without replacement for guaranteed-unique picks.
Generates a cryptographically unguessable, URL-safe Base64 token from OS entropy.
Compares two secrets in constant time, immune to timing-attack byte leakage.
Trace How Each Technique Works
Click through each technique to see its exact behavior:
Seeding the Mersenne Twister PRNG makes every subsequent draw deterministic — essential for reproducible tests and simulations, but never for security.
PRNG, Sampling, and CSPRNG Constructs
These three families cover simulation randomness, selection protocols, and cryptographic security.
random — PRNG (simulations, never security)
random.seed(value)Initializes the Mersenne Twister PRNG deterministically.
random.random()Returns a float uniformly in [0.0, 1.0).
random.randint(a, b)Random integer N with a <= N <= b, inclusive of both endpoints.
random.randrange(a, b)Mirrors range(): excludes the stop boundary [a, b).
Sampling & shuffling
random.choice(seq)Returns a single random element from a non-empty sequence.
random.choices(pop, weights=None, k=n)Samples k elements with replacement; supports relative weights.
random.sample(pop, k=n)Samples k unique elements without replacement.
random.shuffle(x)Mutates a list in place via Fisher-Yates shuffling.
secrets — CSPRNG (tokens, passwords, keys)
secrets.token_hex(nbytes)Cryptographically secure hex-string token, 2×nbytes characters.
secrets.token_urlsafe(nbytes)Cryptographically secure URL-safe Base64 token.
secrets.compare_digest(a, b)Constant-time comparison that defeats timing attacks.
Worked Hands-on Walkthroughs
Progress step-by-step from contrasting PRNG output with secure tokens, through reproducible simulations, to constant-time verification:
Contrasting PRNG Output with Cryptographic Tokens
secrets sources entropy directly from the OS kernel, ensuring generated tokens cannot be reverse-engineered.
import random
import secrets
# 1. Non-cryptographic simulation (random)
random.seed(42)
roll = random.randint(1, 6)
print("Deterministic dice roll (seed=42):", roll)
# 2. Cryptographically secure token (secrets)
api_token = secrets.token_hex(16) # 32 hex characters
session_id = secrets.token_urlsafe(24) # URL-safe Base64 token
print("Secure API Token:", api_token)
print("Secure Session ID:", session_id)secrets sources entropy directly from the OS kernel, ensuring generated tokens cannot be reverse-engineered.
Reproducible Simulation Runs with random.seed()
random.seed() ensures numerical experiments and unit tests execute with perfect deterministic consistency.
import random
def run_monte_carlo_trial(seed_val, iterations=1000):
random.seed(seed_val)
inside_circle = 0
for _ in range(iterations):
x, y = random.random(), random.random()
if x**2 + y**2 <= 1.0:
inside_circle += 1
pi_estimate = round((4 * inside_circle) / iterations, 4)
return pi_estimate
# Independent runs with identical seeds produce identical results!
run1 = run_monte_carlo_trial(12345)
run2 = run_monte_carlo_trial(12345)
print("Run 1 estimate:", run1)
print("Run 2 estimate:", run2)
print("Deterministic equality:", run1 == run2)random.seed() ensures numerical experiments and unit tests execute with perfect deterministic consistency.
Secure Token Generation and Constant-Time Verification
secrets.compare_digest executes in constant time regardless of where string mismatches occur, preventing timing leakage.
import secrets
def generate_password_reset_token():
# Generate a high-entropy 32-byte URL-safe token
return secrets.token_urlsafe(32)
def verify_reset_token(stored_token, submitted_token):
# Constant-time comparison: immune to timing attacks!
return secrets.compare_digest(stored_token, submitted_token)
real_token = generate_password_reset_token()
print("Generated Token:", real_token)
# Verification test
assert verify_reset_token(real_token, real_token) is True
assert verify_reset_token(real_token, "invalid_token_attempt") is False
print("Token verification passed securely!")secrets.compare_digest executes in constant time regardless of where string mismatches occur, preventing timing leakage.
Common Traps & How to Avoid Them
Study the mistakes and clean fixes below before relying on randomness or security tokens in production:
# Mistyped variable or missing closing parenthesis
result = randomness___cryptographic_secrets_val# Declare and verify variables before execution
val = 10
print("Defined correctly:", val)Beginners frequently encounter typos or forgotten definitions before using an identifier.
# Modifying shared state or unexpected variable shadowing
def update_state(data=[]):
data.append(1)
return datadef update_state(data=None):
if data is None:
data = []
data.append(1)
return dataDefault arguments in Python are evaluated once at function definition time, not at invocation time.
# Opening resources in a tight loop without closing or bounding memory
files = [open(f"log_{i}.txt", "w") for i in range(5000)]for i in range(5):
with open(f"log_{i}.txt", "w") as f:
f.write("Safe")Failing to release system resources leads to process termination under heavy production workloads.
Real-World Systems in Action
See how scripts, backend services, and high-throughput authentication systems all lean on the right randomness module at scale:
Local Developer Automation Tool
Individual developers and IT administrators automate everyday repetitive workflows.
A clean standalone script providing fast, local automation with zero dependencies.
import secrets
secure_token = secrets.token_hex(8)
print("Cryptographically secure session token:", secure_token)Backend API Service Integration
SaaS platforms run backend microservices processing requests concurrently.
A modular service handler integrating validation and structured responses.
# Service integration layer
def handle_request(payload: dict) -> dict:
return {"status": "success", "processed": True}High-Throughput Cloud Architecture
Authentication servers MUST use secrets (never random) for password resets, session tokens, and CSRF protection to prevent prediction attacks.
Authentication servers MUST use secrets (never random) for password resets, session tokens, and CSRF protection to prevent prediction attacks.
# High-resilience production pattern
import time
def process_stream(events: list) -> int:
processed = 0
for event in events:
if event:
processed += 1
return processedKey Points & Concept Review
- Never use the random module for security-sensitive tokens, passwords, or keys.
- Use secrets (CSPRNG) for authentication tokens, API credentials, and cryptographic tasks.
- random.seed() ensures deterministic, reproducible simulation runs in scientific code and tests.
- random.choices() samples with replacement and supports weights; random.sample() samples without replacement.
- random.shuffle() randomizes a list in place using the Fisher-Yates algorithm.
- Always use secrets.compare_digest() to compare security tokens to prevent timing attacks.
Frequently Asked Questions & Reference Hub
If a value will ever gate access — a password reset link, a session ID, an API key — default to secrets. The Mersenne Twister behind random is fast and reproducible precisely because it's predictable, which is the opposite of what security needs.
Reference the full API surface of both modules side by side.
Understand why constant-time comparison matters for secrets.
Clarify with-replacement vs without-replacement sampling.
See why 624 observed outputs can reconstruct PRNG state.
Compare the two secure token encodings and when to use each.
Learn patterns for deterministic testing with seeded randomness.
You've Mastered Randomness & Cryptographic Secrets!
You understand random.seed(), choices() vs sample(), shuffle(), secrets tokens, and compare_digest(). Now lock in your knowledge with hands-on practice.
Seed the PRNG, pick a weighted color, and format the deterministic result exactly.
Earn experience points toward your developer rank as soon as you pass.
Bite-sized knowledge check with instant explanations for every question.
Worked example
Pick a random item deterministically using a seed.
import random random.seed(1) print(random.choice(['apple', 'pear']))
How it works, step by step
- random.choice picks an element; seed(1) makes it repeatable.
Random Numbers & Cryptographic Secrets practice
Set random.seed(10). Use random.choice(['red', 'green', 'blue']) to pick a color, and random.randint(1, 100) to pick a number. Print: Picked {color} with score {score}.
Coding Practice is Locked
Sign in to access the interactive Python editor, write and run code checks against automated tests, use hints, and earn XP.
Practice quiz
Check yourself
15 questions with explanations after submission, so you can correct course as you go.
Random Numbers & Cryptographic Secrets quiz
LockedYou must be signed in to take this quiz. Sign in to test your understanding, track your answers, and earn XP.
Lesson incomplete
Not completedCreate an ID or sign in to save lesson completion across devices.