跳到主要内容

随机数生成完全指南:范围、去重、批量与公平抽奖

讲清随机数生成的范围设定、批量与去重玩法,以及抽奖摇号怎么做才公平。重点说明伪随机和密码学随机的差别,帮你选对工具。

发布于 作者 李雷
#随机数生成 #抽奖 #抽样 #密码学随机

随机数生成完全指南:从范围设定到公平抽奖

很多人以为随机数生成就是「随便出个数」,真到了直播抽奖、问卷抽样、班级摇号这些场景,问题立刻冒出来:范围怎么定才不偏?批量出一串数要不要去重?有人质疑「你是不是内定了」时,你拿什么证明这次抽奖是公正的?这篇把这些一次说透。

范围、批量、去重:三个最常用的开关

随机数生成的核心其实就三个参数。

第一个是范围。最小值和最大值都包含在内,这一点很容易栽跟头。范围填 1 到 6,出的是六种结果(一颗公平骰子),不是五种。摇号、骰子、抽奖模拟里,这个差一错会悄悄把概率带偏,而且很难一眼看出来。

第二个是批量。一次只要一个数,适合抽单个中奖者;一次要一串数,适合排顺序、铺测试数据。

第三个是去重。打开「不重复」,就是无放回抽样。比如从 480 张发票里抽 12 张核对,打开去重,12 个行号互不相同,同一张发票不会被查两遍。这里有个反直觉的点:如果你在范围 1 到 50 里要 60 个不重复的数,最多只有 50 个唯一值,工具会返回 50 个就停,这不是 bug,而是抽样该有的行为。要么放宽范围,要么关掉去重。

一个真实例子:从 1 到 100 取 5 个不重复

假设你要从 100 个候选编号里抽 5 个,且不能重复。设置很简单:最小填 1,最大填 100,批量填 5,打开去重,点一次。

某一次的输出可能是:73 8 51 96 27

刷新再点,这五个数会完全不一样,因为每次点击都重新抽取。这正是抽样想要的效果。如果你换成有放回(关掉去重),理论上有可能抽到两个 73,这在「同一个人不能中两次」的抽奖里就是事故。所以场景对了,开关才不会错。想直接上手试,可以打开 随机数生成工具,范围和批量都摆在最显眼的位置。

伪随机 vs 密码学随机:差别比你想的大

这是最容易被忽略、却最关键的一环。

很多在线小工具底层用的是 Math.random。它快,但它是伪随机:由一个种子推算出一串看似杂乱的数,算法和内部状态如果被人摸清,后面的输出就能被预测出来。做个小游戏掷骰子无所谓,但拿来抽奖、发邀请码、生成账号 ID,就埋了隐患。

更稳的做法是用密码学安全随机,也就是 crypto.getRandomValues。它的种子来自操作系统的熵池(Linux 的 /dev/urandom、macOS 的 getentropy、Windows 的 BCryptGenRandom),跟 TLS 握手、WebAuthn 用的是同一份源。结论很直接:crypto 随机比 Math.random 更安全,因为它不可预测,旁人没法靠观察前几个输出反推下一个。批量造测试数据时,它铺出来的分布也比你在控制台随手写的 Math.random 循环要均匀得多。

我自己第一次认真在意这件事,是给一次抽奖写脚本。当时图省事用了 Math.random,事后被同事追问「凭什么相信这个数没被动手脚」,我一句话也接不上。后来换成 crypto 随机,再加上录屏留证,才算把「公平」这两个字落到实处。

抽奖、抽样、摇号:怎么做才站得住脚

公平不只是技术问题,还是流程问题。

抽奖。你答应粉丝从 230 条评论里抽 1 个,范围填 1 到 230,点一次,出来的整数就是中奖楼层。因为用的是密码学随机、没有种子、无法回放,没人能说你内定了熟人。记得开屏录像,事后想复盘也有据可查。

抽样。从一批样本里抽固定份数做抽查,打开去重就够了,省掉表格里 RANDBETWEEN 撞号后还要手动清理的麻烦。

摇号、排顺序。八个人排发言顺序,生成范围 1 到 8、不重复的一组数,出来的就是顺序。三秒搞定,屋里那句「凭啥总是我最后讲」也就没了。

要注意:密码学随机故意做成不可复现,每次点都抽新的熵。如果你需要一段别人能核验、能复算的序列(比如要公开的研究抽样),那就该在脚本里换成可设种子的伪随机算法,让别人用同一个种子复算出同样结果。两种需求,选两种工具,别用错。

把随机用在更多地方

随机数生成只是起点。如果你要的是掷骰子的体验而不是裸数字,试试 骰子模拟器,它把同一套随机逻辑包成了骰面。涉及概率换算、占比计算的场景,也能顺手配合相应的计算工具,把「抽中谁」和「中奖率多少」一起算清楚。

记住三件事就够了:范围两端都含、按场景决定要不要去重、对公平有要求就用密码学随机并留证。把这三点做对,你的每一次抽奖和摇号都经得起人问。


Made by Toolora · Updated 2026-06-13