抽奖这件小事,公平性比随机性更难
每隔一段时间都会遇到「从名单里抽几个人」的需求:运营抽奖、内测名额分配、随机分组……这类任务看起来微不足道,但做过几次之后我发现,技术上最简单的部分——「随机」——其实不是难点。真正麻烦的是:怎么让参与者相信结果是公平的。
随机不等于公平
用 Math.random() 随机选一行,代码三行搞定。但事后一旦有人质疑「是不是内定的」,你拿什么证明?
这就是「随机性」和「可信度」的分裂点。随机性是计算问题,可信度是信任问题。工程上处理可信度,需要额外三件事:
- 可重现:记录随机种子,任何人用同一个种子跑同一份名单,必须得到相同结果。
- 可审计:记录执行时间戳、总条目数、选中的行号,而不只是「抽到了谁」。
- 幂等输入:确保抽奖前对名单做了去重和排序,否则同一份「名单」不同顺序就会导致不同结果——即使种子相同。
用 AI 做这件事有一个天然优势:可以把整个过程用自然语言叙述出来,自动生成带时间戳的结果报告,作为公示材料直接发出去。
我的做法
把抽奖任务交给 AI 时,我会附带几条约束:
从这份名单抽取 3 名获奖者(不重复),要求:
- 使用密码学安全随机,而非伪随机
- 输出:总条目数 / 选中行号 / 完整信息 / 执行时间
- 如需排除之前已中奖的人,列出排除名单
输出样例大概是这样:
总条目:247 人(已去重)
执行时间:2026-03-15 14:32:18 UTC
获奖者:
- 第 142 行:张三(zhang@example.com)
- 第 89 行:李四(li@example.com)
- 第 201 行:王五(wang@example.com)
选取方法:密码学随机(CSPRNG)
这份输出可以直接截图公示,有行号可以对照原始名单,时间戳防止事后修改。
核心原则
「随机」只是起点,「可验证」才是终点。任何抽奖系统,都应当在设计之初就回答:如果有人质疑,我能拿出什么证据?
几个常见的坑
名单来源不一致:从 Google Sheets 导出和从本地 CSV 读取,字段顺序可能不同,导致「同一份名单」其实是两份不同的输入。在抽奖前锁定一份规范化的名单文件,并记录其 MD5,是好习惯。
加权抽奖没有文档化:「购买两次的用户有两倍中奖概率」这类规则,如果没有在结果报告里写清楚权重计算逻辑,事后一定有人质疑。权重规则应和随机结果一起公示。
备选名单顺序暗示偏好:抽完 1 名正式获奖者,再抽 3 名候补,候补顺序最好也随机排列,而不是「谁先被抽到谁排前面」——后者会让候补 1 号看起来比候补 3 号更被「看好」。
一句话心法
抽奖的本质是信任转移——把人工决策的主观性,转移到算法可验证的客观性上。随机是手段,审计是目的。