Part 3 · Classic Paradoxes 经典悖论

3.2 The Birthday Paradox 生日悖论:23 个人的房间,以及巧合的真实价格

难度 ★★☆ 阅读 + 玩 ~18 min 直觉翻车率 高 前置 1.1 概率是什么
Guess First 先猜一次

要多少人才够

一个房间里的人,生日(只算月和日)随机分布。

要让「房间里存在两个人生日同一天」的概率超过一半,最少需要多少人?

押好了。再押一个:要让「有人和你同一天生日」超过一半,又需要多少人?两个数字差得比你想的远。
Core Concept 核心概念

你算的是自己,题目问的是所有人

答案是 23 人。大多数人的第一反应是一百多,因为脑子里默默算的是「365 天,得凑够一半才行」。这个直觉之所以差这么远,原因只有一个,而且极其简单:

你在数「人」,而题目在数「配对」。

「两个人生日相同」是一件发生在一对人身上的事,不是发生在一个人身上的事。所以真正该数的是房间里有多少对:

n 个人的配对数 = n × (n − 1) ÷ 2

10 个人 → 45 对
23 个人 → 253 对
50 个人 → 1,225 对
100 个人 → 4,950 对

人数翻一倍,配对数大约翻四倍——它按平方长。

23 个人只是 23 个人,但他们之间藏着 253 次「撞上生日」的机会。而每一对撞上的概率是 1/365。粗略地看,253 ÷ 365 ≈ 0.69,已经和 1 是同一个量级了——出现至少一次碰撞一点也不奇怪。

把它精确算出来

直接算「至少有一对相同」很麻烦(要处理各种重复情况),但算它的反面很容易:所有人生日都不同。

第 1 个人:随便哪天都行 → 365/365
第 2 个人:得避开 1 天 → 364/365
第 3 个人:得避开 2 天 → 363/365
…
第 23 个人:得避开 22 天 → 343/365

全都不同的概率 = 这 23 个分数连乘 ≈ 49.3%
所以「至少有一对相同」≈ 100% − 49.3% = 50.7%

关键在于每多一个人,要避开的日子就多一天——连乘的每一项都在变小,而且越乘越快。这就是那个平方增长在算式里的样子。

那个「一百多」的直觉,其实回答的是另一道题

你的直觉不是无中生有,它只是算错了对象。「有人和我同一天生日」这道题,答案确实是一百多:

房间里有 23 人时:
· 存在任意两人同生日 → 50.7%
· 有人和我同生日 → 只有 5.9%

要让「有人和我同生日」超过一半,需要 254 人。

差了十倍。原因还是那个:以「我」为中心时,只有 22 条配对关系;不指定中心时,有 253 条。直觉之所以出错,是因为它总是把自己放在中心——而巧合从来不在乎谁是中心。

这就是本章真正的用处,而且它远远超出生日。每当你惊叹「怎么这么巧」的时候,先问一句:「一共有多少次机会撞上?」你惊叹的通常是「这件事发生在我身上的概率」,而实际发生的是「这件事发生在任何人、任何时候、任何配对上的概率」。后者往往大得多,多到「巧合」根本不需要解释。4.3 章会把这一招用在癌症村和轰炸落点上。

Interactive Lab 交互实验

看着配对数糊成一团

圆环上每个点是一个人,每条线是一对。拖动人数滑块,注意线的数量增长得比点快得多。右边同时给出两条曲线:青绿线是「任意两人同生日」,灰线是「有人和我同生日」——它们分道扬镳的样子,就是这道题全部的秘密。

Birthday Collisions · 配对连线与碰撞概率
253 对
配对关系的总数
50.7%
任意两人同生日
5.9%
有人和「我」同生日

概率曲线

100% 50% 0% 0 人 23 100 人
任意两人同生日 有人和「我」同生日

随机造一千个房间

49.1%
1000 间房里实际出现同生日的比例
50.7%
理论值(对照)

把滑块从 2 慢慢拖到 60,盯着两条曲线。青绿线在 20 人上下猛地窜起,到 50 人时已经贴上天花板(97%);灰线爬得像蜗牛,到 100 人才刚过 23%。同一个房间,同一批人,两个问题的答案差着一个数量级——而它们在日常语言里听起来几乎是同一句话。

另外注意模拟值和理论值的关系:1000 间房的实测(49.1%)和理论(50.7%)差了 1.6 个百分点。这不是程序错了,是 1.1 章讲过的抽样波动——1000 次抽样的标准差约 1.6 个百分点,所以这个偏差正好在意料之中。点几次「重跑」就能看到它在理论值两侧跳。

Case Study 真实案例

同一个数学,把 SHA-1 拉下了马

SHAttered · Google & CWI Amsterdam, 2017

生日悖论看起来像个派对小把戏,实际上它是密码学里一条硬约束的名字。

哈希函数把任意长度的文件压成一个固定长度的指纹。它的安全性依赖一件事:找不到两个不同的文件、指纹却相同——这种情况叫collision(碰撞)。如果能造出碰撞,攻击者就能拿一份被签名认可的合同,换成另一份内容完全不同、指纹却一模一样的合同。

那么找一个碰撞有多难?直觉会说:指纹有 n 位,就有 2ⁿ 种可能,得试 2ⁿ 次。但这是「有人和我同生日」的算法。攻击者不需要撞上某个指定的指纹,他只要任意两份文件撞在一起就行——那是「任意两人同生日」的算法:

生日界(birthday bound):n 位的哈希,只需要约 2^(n/2) 次尝试就有相当概率撞出碰撞。

SHA-1 有 160 位 → 强度不是 2¹⁶⁰,而是约 2⁸⁰
开平方,指数直接减半。

这就是为什么密码学界从 2005 年起就不断警告 SHA-1 已经不安全——王小云等人当年给出的分析把攻击代价压到了远低于 2⁸⁰ 的水平。但警告归警告,SHA-1 在实践中仍被广泛使用了十多年,理由通常是「理论攻击不等于现实攻击」。

2017 年 2 月,Google 研究院与荷兰 CWI 的研究者公布了 SHAttered:两份内容不同、SHA-1 指纹完全相同的 PDF 文件,可以下载、可以自己验证。

2⁸⁰
生日界给出的 SHA-1 碰撞强度(而非 2¹⁶⁰)
2 份 PDF
内容不同、SHA-1 完全相同
2017.2
公布后各大系统加速淘汰 SHA-1

公布后,主流浏览器、证书颁发机构和版本控制系统迅速加快了淘汰 SHA-1 的进度。这也是为什么今天的标准是 SHA-256——256 位的生日界是 2¹²⁸,这个数字大到目前没有任何可预见的技术能碰它。

这个案例最漂亮的地方在于:让 SHA-1 倒下的不是什么高深的新数学,而是「你数错了配对数」这件事——和 23 个人的房间是同一个错误。设计者以为自己有 2¹⁶⁰ 的安全余量,实际只有 2⁸⁰;差的那一半指数,就是生日悖论收走的。

来源:Marc Stevens, Elie Bursztein, Pierre Karpman, Ange Albertini, Yarik Markov, "The first collision for full SHA-1"(CRYPTO 2017;项目页 shattered.io,2017 年 2 月公布)。SHA-1 的早期分析见 Wang, Yin & Yu, "Finding Collisions in the Full SHA-1", CRYPTO 2005。生日界为标准密码学结论,见任意密码学教科书中关于生日攻击的章节。
Quiz 自测

章末自测

计算题一个 30 人的班级。(a)有多少对同学?(b)「至少两人同生日」的概率约是多少?(c)如果老师问的是「有没有人和我(老师)同一天生日」,概率又是多少?

(a) 30 × 29 ÷ 2 = 435 对。

(b) 全都不同的概率 = (365/365)(364/365)…(336/365) ≈ 29.4% → 至少两人相同 ≈ 70.6%。可以在实验里把滑块拖到 30 验证。

(c) 每个学生和老师不同天的概率是 364/365,30 个学生全都不同 = (364/365)³⁰ ≈ 92.1% → 至少一人相同 ≈ 7.9%。

把 (b) 和 (c) 摆在一起:70.6% 对 7.9%,差了将近九倍。一个 30 人的班里几乎肯定有同生日的两个人,但老师撞上其中一个的机会不到一成。这就是「有没有」和「是不是我」的区别。

概念题为什么配对数按 n² 增长,会让「巧合」变得如此廉价?请用一个生日之外的例子说明。

因为我们习惯用「样本量」来估计惊讶程度,而巧合的机会数由「组合数」决定,后者涨得快得多。n 个东西两两配对是 n²/2 量级;如果巧合需要三个东西同时对上,那是 n³/6 量级,涨得更疯。

例子一:股票预测。一个基金经理连续五年跑赢大盘,听起来很神。但如果市场上有 10000 个基金经理,纯靠运气连对五年的人数期望是 10000 × (1/2)⁵ ≈ 312 人。你在新闻上看到的那位,多半就是从这 312 人里被挑出来的。这也是 4.4 章的主题。

例子二:「我梦见的事第二天发生了」。假设一个人每晚做的梦里,有百万分之一的概率碰巧对上第二天的某件事。听起来绝无可能——但全国有几亿人,每人每晚做好几个梦。每天全国出现几百上千次「预知梦」是必然的,而每一次都会被当事人当作奇迹讲述几十年。

共同的结构:你惊讶的是「这件事发生在我身上的概率」,实际发生的是「这件事发生在任何人身上的概率」。后者要乘上一个巨大的机会数。

场景判断某彩票开奖号码在两个月内重复出现了一次,媒体质疑「一定有内幕」。假设每期从 4000 万种组合中随机开出一注,每周开 3 期,已经开了 20 年。这个重复值得怀疑吗?

先数机会数。20 年 × 52 周 × 3 期 ≈ 3120 期。这些期数之间的配对数是 3120 × 3119 ÷ 2 ≈ 486 万对。

每一对撞上的概率是 1/4000 万。所以期望的重复次数 ≈ 486 万 ÷ 4000 万 ≈ 0.12 次。至少出现一次重复的概率约 11%。

结论:一次重复不算特别可疑,大约十分之一的机会。它不是「必然会发生」的那种廉价巧合,但也远没到需要用内幕来解释的地步。如果重复了三四次,那才值得查。

注意这道题的做法:不去问「这一期和那一期撞上的概率」(那确实是四千万分之一),而去问「所有期数之间,一共有多少次撞上的机会」。媒体报道里那个「四千万分之一」不是编的,它只是回答了一道没人在问的题——和 2.3 章检察官谬误的结构一模一样。

思考题如果一年有 1000 天(而不是 365 天),要多少人才能让「至少两人同生日」超过一半?能不能找出一个不用连乘的估算公式?

估算思路:n 个人有约 n²/2 对,每对撞上的概率是 1/d(d 为一年的天数)。期望的碰撞次数 ≈ n²/(2d)。当这个期望约等于 0.7 时,「至少一次」的概率大致过半(因为 1 − e^(−0.7) ≈ 0.50)。

n²/(2d) ≈ 0.7 → n ≈ 1.18 × √d

验证 d = 365:n ≈ 1.18 × 19.1 ≈ 22.5,实际答案 23。相当准。

所以 d = 1000:n ≈ 1.18 × 31.6 ≈ 37 人。(精确计算给出 38 人,估算已经够用。)

这个 √d 才是本章最该带走的东西。一年的天数翻四倍,需要的人数只翻一倍。它同时也是上面 SHA-1 案例的核心:2¹⁶⁰ 种指纹开平方就是 2⁸⁰ 次尝试。无论对象是生日、哈希值还是彩票号码,撞车所需的次数永远是可能性总数的平方根量级——这条规律的名字就叫生日界。