随机:乱敲键盘能敲出什么 书架

第 08 章 / 共 12 章

第八章 · 计算机怎么假装随机

冯·诺依曼——现代计算机架构的设计者——1951 年留下一句名言:「任何以为用算术方法能产生随机数字的人,当然是生活在罪恶之中。」他不是在骂谁,是在陈述一个结构性事实:计算机是一台彻底的确定性机器。同一个程序、同一个输入,永远给同一个输出。让它产生「随机」,等于让它做自己最做不到的事。

但你的代码里 random() 每天都在跑。它在干什么?答案是:假装。

线性同余:一个除余数的轮回

最经典的假装方案叫线性同余发生器(LCG)——大白话讲,就是一条递推式:

下一个数 = (a × 当前数 + c) mod m

从某个「种子」(初始值)出发,反复套这条式子:乘一乘、加一加、除一除取余数。余数的序列看起来忽大忽小、毫无规律——拿它当随机数用。所谓 random(),多数时候就是这么一条式子在空转。

注意三个直接推论:

假装会露馅:RANDU 的灾难

「看起来像」和「经得起看」之间隔着深渊。1960 年代,IBM 在大型机上标配了一个 LCG 叫 RANDU,参数没选好,留下了计算机史上最著名的随机数事故:把 RANDU 连续生成的三个数当成三维坐标画点,所有点竟然整整齐齐躺在 15 个平面上——三维空间里本该均匀撒开的点,实际是一摞平行的薄片。

后果很实际:当年大量用 RANDU 做的蒙特卡洛模拟(第十章会讲这种方法),结果都有系统性偏差——你以为你在整个空间里均匀采样,其实只采了 15 片「夹层」。无数论文的结论建立在这种「假均匀」上。 Marsaglia 后来那句刻薄的总结成了行规:「随机数发生器不该是随便选的参数凑出来的。」

大白话:伪随机数的可怕之处不是它假,而是它假得很有结构——肉眼看是噪声,放进正确的维度里看,是整齐的栅栏。用它做模拟,等于在一把弯尺上量布。

现代的假装:又好又长的磁带

今天的默认选择(Python 的 random、Excel 的 RAND)是梅森旋转(Mersenne Twister)——大白话讲,一个把内部状态搅得极其充分的伪随机发生器。它的周期是 2^19937 − 1,长到把宇宙里每个原子每纳秒取一个数、取到宇宙热寂也播不完;统计性质通过了几乎所有常规检验;而且快。

但它依然是「磁带」:知道种子就能重播全部,观察到足够多的输出(624 个连续输出)就能反推出内部状态、预测未来所有输出。所以它从头到尾都在文档里印着警告:不可用于密码学。模拟、游戏、洗牌尽管用;密钥、令牌、抽奖——碰都别碰。这个分水岭第十一章会正式接管。

假装也是一种美德

别急着瞧不起伪随机。「确定地假」恰恰是它的核心价值:

伪随机的定位想清楚了其实很优雅:它提供的不是随机性,是「按方抓药的复杂性」——一种低成本、可复现、统计上足够好的「乱」。它欠的那一味药——真正的不可预测——得去物理世界里找。下一章,我们去看看真随机从哪里来,以及怎么验货。

随机:乱敲键盘能敲出什么 · J
费曼式写法 · 由多个 AI 代理撰写与互相审校