核心答案:日常「随机数」几乎都是伪随机——用确定性算法从种子算出貌似无规律的序列。种子相同,序列完全相同。这对游戏、模拟足够;但密码、密钥必须用基于物理噪声的真随机或加密级随机数生成器(CSPRNG)。

伪随机与真随机

类型来源可复现典型用途
伪随机(PRNG)数学算法(如梅森旋转)是(同种子同序列)游戏、模拟、抽样
加密随机(CSPRNG)系统熵池 + 加密算法密码、Token、密钥
真随机(TRNG)物理噪声(热噪声、量子)彩票摇奖、军事密钥

JS 的 Math.random() 是伪随机且非加密安全;安全场景用 crypto.getRandomValues()。

随机数怎么生成

线性同余法(经典教学模型):Xₙ₊₁ = (aXₙ + c) mod m

  • 选好 a、c、m 可让周期达到 m
  • 实例:a=1103515245、c=12345、m=2³¹(glibc 经典参数)
  • 种子 X₀ 决定整条序列——「时间戳做种子」是常见做法

梅森旋转算法:周期 2¹⁹⁹³⁷−1,Python/JS 引擎的主流默认,统计性质优异。

常见应用场景

  1. 抽奖/抽签:均匀分布整数,1-N 每数概率 1/N
  2. 游戏:暴击判定、掉落率(如 20% 暴击 = 随机数 < 0.2 触发)
  3. 模拟(蒙特卡洛):大量随机采样估算 π、积分、风险
  4. 洗牌:Fisher-Yates 算法 O(n) 且无偏
  5. 验证码/临时密码:必须 CSPRNG

随机范围与公平性

  • [min, max] 整数公式:Math.floor(Math.random() × (max−min+1)) + min
  • 1-100:floor(random × 100) + 1
  • 常见偏差:用 random() % n 取模,当 n 不整除范围长度时小数字概率略高(模偏差),正式场景用拒绝采样

实例:班级 45 人抽 1 人答问,random 生成 1-45 每人生概率 2.22%;连抽 3 人不重复需记录已抽编号排除。

常见误区

  • 「连续 5 次正面,下次反面概率大」:赌徒谬误。独立事件概率不变,硬币无记忆
  • Math.random() 生成密码:可被预测(种子可推断),必须用 crypto.getRandomValues()
  • 「随机就是没有规律」:真随机也允许出现 11111——均匀随机长串中必然出现局部「规律」片段
  • 手动乱按键盘当随机源:人类「随机」行为高度可预测(偏爱中间区域、回避重复)