Python random
random vs secrets, seeding, shuffling, and why random is not for passwords.
Key Points`random` is a Mersenne Twister — fast but predictable; anything security-related must use `secrets`.
Basic Randomness
random produces pseudo-random numbers: the same seed always yields the same sequence — a weakness for security, a feature for reproducible experiments.
Python
import random
random.random() # 0.0 ~ 1.0 的浮点
random.uniform(1, 10) # 区间浮点
random.randint(1, 6) # 闭区间整数(含 6)
random.randrange(0, 10, 2) # 同 range,不含 10
random.seed(42) # 固定种子,结果可复现
print(random.randint(1, 100))Output
0.6394267984578837
4.914371084897312
4
4
82Choice, Shuffle, Sample
choice picks one, choices samples with replacement and weights, sample samples without replacement, shuffle shuffles in place and returns None.
Python
import random
cards = ["A", "K", "Q", "J"]
print(random.choice(cards))
print(random.choices(cards, k=3)) # 可重复
print(random.choices(cards, weights=[10, 1, 1, 1], k=3)) # 权重
print(random.sample(cards, 2)) # 不重复
random.shuffle(cards)
print(cards)Output
Q
['A', 'A', 'J']
['A', 'A', 'K']
['K', 'J']
['J', 'A', 'Q', 'K']Security: Use secrets
Never use random for passwords, tokens or OTPs — its internal state can be recovered from outputs. secrets reads the OS cryptographic source.
Python
import secrets
import string
alphabet = string.ascii_letters + string.digits
print("".join(secrets.choice(alphabet) for _ in range(16)))
print(secrets.token_hex(16)) # 32 位十六进制
print(secrets.token_urlsafe(16)) # URL 安全
print(secrets.randbelow(100)) # 0~99Output
k9Qm2XvT7bLpR4nZ
8f3c1d9a7b2e5f6048c3a1d9b7e5f206
Xk3nQ9vT2bLpR7mZ4
37With the same seed
random is fully reproducible — useful in tests, but never expose the seed or seed from a timestamp.基础随机
random 生成的是伪随机数:同一个种子必然得到同一串结果。这既是缺点(可预测),也是优点(可复现实验)。
Python
import random
random.random() # 0.0 ~ 1.0 的浮点
random.uniform(1, 10) # 区间浮点
random.randint(1, 6) # 闭区间整数(含 6)
random.randrange(0, 10, 2) # 同 range,不含 10
random.seed(42) # 固定种子,结果可复现
print(random.randint(1, 100))Output
0.6394267984578837
4.914371084897312
4
4
82选择、打乱、抽样
choice 取一个,choices 可重复带权重取多个,sample 不重复取,shuffle 原地打乱。注意 shuffle 会修改原列表且返回 None。
Python
import random
cards = ["A", "K", "Q", "J"]
print(random.choice(cards))
print(random.choices(cards, k=3)) # 可重复
print(random.choices(cards, weights=[10, 1, 1, 1], k=3)) # 权重
print(random.sample(cards, 2)) # 不重复
random.shuffle(cards)
print(cards)Output
Q
['A', 'A', 'J']
['A', 'A', 'K']
['K', 'J']
['J', 'A', 'Q', 'K']安全场景用 secrets
生成密码、令牌、验证码时不能用 random —— 它的内部状态可以从少量输出反推。secrets 直接读操作系统的密码学随机源。
Python
import secrets
import string
alphabet = string.ascii_letters + string.digits
print("".join(secrets.choice(alphabet) for _ in range(16)))
print(secrets.token_hex(16)) # 32 位十六进制
print(secrets.token_urlsafe(16)) # URL 安全
print(secrets.randbelow(100)) # 0~99Output
k9Qm2XvT7bLpR4nZ
8f3c1d9a7b2e5f6048c3a1d9b7e5f206
Xk3nQ9vT2bLpR7mZ4
37random 的序列在同一种子下完全一致,测试里可以用它复现;但绝不要把种子暴露给用户,也不要用时间戳做种子。