随机数生成器:抽奖/抽号
年会抽奖要随机选幸运观众、班级活动要随机点名、网页登录验证码要随机数——随机数生成器是高频小工具。本文详解随机数生成器的用法。
52tool 随机数生成器
工具地址:UUID 生成器(含随机数功能)
功能
- 单个随机数
- 范围内随机数
- 批量生成
- 不重复随机数
- 随机排序
- 浏览器端生成
实战 1:单个随机数
输入:
范围:1-100
输出:47
实战 2:批量生成
输入:
范围:1-100
数量:10
不重复:是
输出:[47, 23, 89, 12, 56, 78, 34, 91, 5, 62]
实战 3:随机排序
输入:
列表:[张三, 李四, 王五, 赵六]
操作:随机排序
输出:[李四, 赵六, 张三, 王五]
随机数原理
伪随机数(PRNG)
计算机生成的"随机数"通常是伪随机,用算法生成:
种子 → 算法 → 序列
- 同一种子生成相同序列
- 速度快
- 统计学上像随机
- 不能用于密码学
真随机数(TRNG)
物理现象生成:
- 大气噪声
- 量子噪声
- 放射性衰变
- 不可预测
- 速度慢
- 用于密码学
JavaScript 中的随机
// 伪随机
Math.random(); // 0-1
// 密码学安全随机
crypto.getRandomValues(new Uint32Array(1));
Python 中的随机
import random
# 伪随机
random.randint(1, 100)
# 密码学安全
import secrets
secrets.randbelow(100)
实战场景
场景 1:年会抽奖
公司年会,500 人参与,抽 3 名一等奖:
- 给每位员工编号 1-500
- 用 52tool 随机数生成器
- 范围 1-500,数量 3,不重复
- 生成 3 个号
- 对应员工中奖
场景 2:班级点名
老师随机点名提问:
- 学生编号 1-40
- 范围 1-40,数量 1
- 生成
- 对应学生回答
场景 3:分组
40 人分成 8 组,每组 5 人:
- 生成 1-40 的随机排列
- 顺序切成 8 组
- 每组 5 人
场景 4:摇号买房
1000 套房,2000 人买:
- 编号 1-2000
- 生成不重复随机数 1000 个
- 顺序选房
场景 5:AB 测试
10000 用户分两组:
- 生成 0-1 的随机数
- < 0.5 是 A 组
- ≥ 0.5 是 B 组
场景 6:验证码
6 位数字验证码:
范围:0-9
长度:6
输出:384729
场景 7:随机选择
今天吃什么?列 5 个选项随机选:
列表:[面, 饭, 粥, 馒头, 面包]
操作:随机选 1
输出:粥
场景 8:随机密码
字符集:A-Z a-z 0-9 !@#$
长度:16
输出:X7#kP9mQv!2nL8wR
参考 52tool 密码生成器。
不同需求选择不同工具
1. 简单随机数
用浏览器:
Math.floor(Math.random() * 100) + 1; // 1-100
2. 不重复随机数
需要洗牌算法:
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
const numbers = Array.from({length: 100}, (_, i) => i + 1);
const picked = shuffle(numbers).slice(0, 10);
3. 加密随机
const array = new Uint32Array(1);
crypto.getRandomValues(array);
console.log(array[0] % 100 + 1); // 1-100
4. 真随机
random.org 提供真随机数服务(基于大气噪声):
https://www.random.org/
编程实现
JavaScript
// 单个随机数
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 不重复批量
function randomUnique(min, max, count) {
const pool = Array.from({length: max - min + 1}, (_, i) => i + min);
for (let i = pool.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[pool[i], pool[j]] = [pool[j], pool[i]];
}
return pool.slice(0, count);
}
// 加密安全
function secureRandomInt(min, max) {
const range = max - min + 1;
const array = new Uint32Array(1);
crypto.getRandomValues(array);
return min + (array[0] % range);
}
Python
import random
# 单个
n = random.randint(1, 100)
# 不重复批量
nums = random.sample(range(1, 101), 10)
# 随机选择
choices = ['张三', '李四', '王五']
picked = random.choice(choices)
# 随机排序
shuffled = random.sample(choices, len(choices))
# 加密安全
import secrets
n = secrets.randbelow(100) + 1 # 1-100
命令行
# Linux
echo $RANDOM # 0-32767
shuf -i 1-100 -n 1 # 1-100 单个
shuf -i 1-100 -n 10 # 10 个
# PowerShell
Get-Random -Minimum 1 -Maximum 100
Excel
=RANDBETWEEN(1, 100) # 1-100 单个
=RANDBETWEEN(1, 100) & RANDBETWEEN(1, 100) # 两位
抽奖公平性
公平的随机
- 算法公开
- 种子可验证
- 过程可监督
- 结果不可预测
防作弊
- 现场生成(非提前)
- 多方见证
- 录像记录
- 区块链存证
区块链随机数
Chainlink VRF 等提供可验证随机数:
请求 → 链上生成 → 不可篡改 → 验证
用于链上抽奖、NFT 分配等。
实战:年会抽奖系统
需求
- 500 名员工
- 抽 3 等奖:30 名(每人 100 元)
- 抽 2 等奖:10 名(每人 500 元)
- 抽 1 等奖:3 名(每人 5000 元)
- 特等奖:1 名(10000 元)
实现
import random
employees = list(range(1, 501)) # 1-500 编号
# 3 等奖
random.shuffle(employees)
winners_3 = employees[:30]
remaining = employees[30:]
# 2 等奖
random.shuffle(remaining)
winners_2 = remaining[:10]
remaining = remaining[10:]
# 1 等奖
random.shuffle(remaining)
winners_1 = remaining[:3]
remaining = remaining[3:]
# 特等奖
random.shuffle(remaining)
winner_special = remaining[0]
print('3 等奖:', winners_3)
print('2 等奖:', winners_2)
print('1 等奖:', winners_1)
print('特等奖:', winner_special)
公开性
- 现场公示代码
- 用现场提供的种子(如员工代表说一个数)
- 录屏过程
- 当场公布结果
进阶技巧
技巧 1:加权随机
抽奖时 VIP 中奖概率高 3 倍:
import random
participants = ['A', 'B', 'C', 'D'] # 普通用户
weights = [1, 1, 1, 3] # D 是 VIP,权重 3
winner = random.choices(participants, weights=weights, k=1)[0]
技巧 2:随机分组
40 人随机分 8 组:
import random
people = list(range(1, 41))
random.shuffle(people)
groups = [people[i:i+5] for i in range(0, 40, 5)]
for i, group in enumerate(groups):
print(f'第 {i+1} 组:', group)
技巧 3:保证不重复
用洗牌算法保证:
def draw_lots(participants, count):
pool = participants.copy()
random.shuffle(pool)
return pool[:count]
技巧 4:可验证随机
import hashlib
import random
# 用现场种子
seed_input = input('请输入现场种子: ')
seed = int(hashlib.sha256(seed_input.encode()).hexdigest(), 16)
random.seed(seed)
# 之后随机数固定
winners = random.sample(range(1, 501), 3)
事后验证:用相同种子能重现结果。
技巧 5:避免 PRNG 周期
PRNG 有周期(如 LCG 周期 2^32)。短周期在小范围内随机有偏差。用 Mersenne Twister(Python 默认)周期 2^19937-1,足够长。
与其他工具配合
随机数 + 密码生成
工具:密码生成器
随机数扩展为强密码。
随机数 + UUID
工具:UUID 生成器
UUID v4 是密码学安全随机数。
随机数 + 抽奖
工具:在线抽奖工具
年会、活动抽奖场景。
常见问题
Q: 在线工具的随机数公平吗?
A: 52tool 用浏览器端 crypto.getRandomValues,是密码学安全随机源。但抽重要奖项建议用现场工具,过程可监督。
Q: 怎么保证抽奖不重复?
A: 用洗牌算法:把所有参与者洗牌,依次取出,自然不重复。
Q: 1-100 中 50 的概率是多少?
A: 均匀分布下每个数概率 1/100 = 1%。
Q: 能生成负数随机数吗?
A: 能。范围设为 -100 到 100 即可。编程用 random.randint(-100, 100)。
Q: 随机数种子是什么?
A: PRNG 的起始值。同一种子生成相同序列。需要真随机时用 crypto 库或 random.org。
Q: 工具会泄露我的数据吗?
A: 52tool 随机数生成器在浏览器端运行,输入不上传服务器。适合抽奖等敏感场景。
常见问题解答
Q: 怎么在 1-100 中随机选 10 个不重复的数?
A: 用 52tool 随机数生成器,设置:1) 范围 1-100;2) 数量 10;3) 不重复:是;4) 生成。
Q: 怎么在 100 人中抽奖 5 名?
A: 1) 给每人编号 1-100;2) 用工具生成 5 个不重复随机数;3) 对应编号的中奖。
Q: 怎么保证抽奖公平?
A: 1) 现场生成(非提前);2) 公示代码/工具;3) 多方见证;4) 录屏;5) 用可验证随机数(如区块链 VRF)。
Q: 随机数能预测吗?
A: 伪随机数(Math.random)理论上可预测,但实际很难。加密随机数(crypto)不可预测。真随机数(random.org)完全不可预测。
Q: 怎么实现加权抽奖?
A: VIP 权重 3,普通权重 1。用 random.choices(weights=[3, 1, 1])。在线工具多数不支持加权,需要编程。
Q: 怎么生成 4 位验证码?
A: 范围 0-9,长度 4。用工具或代码:''.join([str(random.randint(0, 9)) for _ in range(4)])。
总结
随机数生成器是日常高频小工具:
- 在线生成 → 52tool 随机数
- 不重复 → 用洗牌算法
- 加密安全 → 用 crypto 库
- 真随机 → random.org
记住:抽奖场景用浏览器端工具,重要场景可验证,密码用加密随机。