随机数是如何生成的
引出
在现实中, 会有抛硬币猜正反的操作, 硬币要么是正, 要么是反, 在揭晓之前, 我们谁也不知道它现在的状态. 而这, 是因为其中存在着很大的不确定因素, 如抛硬币的力度、抛硬币的角度、接硬币的力度和角度、硬币的重量、当前风速等等.
但是在计算机中, 要想生成一个随机数, 就需要通过一个算法来实现, 那么生成随机数的算法是如何实现的呢? 简单想一下这个事情, 通过确定的输入, 确定的步骤, 输出不确定的值? 这还是计算机干的事情吗?
当然不是, 所以一直都在说函数生成的是伪随机数
而不是真正的随机数. 伪随机数
是什么呢? 我理解的就是, 虽然生成的数不是随机的, 但是在进行概率统计时是均匀分布的, 虽然数字不是真正随机的, 但是可以满足日常使用就够了.
在计算机中生成随机数, 肯定要告诉它具体的操作步骤, 而步骤一旦确定, 生成的结果序列就确定了, 这也是为什么在调用随机数生成函数的时候需要设定随机种子了, 因为函数是固定的, 如果输入也固定, 那结果就不会发生变化了. 这个随机种子在实际中一般都使用当前时间戳.
所以, 现在问题就可以这样描述了: 设定函数 f(x), 结果为[a, b, c, d...]. 其结果序列在随机区间均匀分布.
那么如何生成这个函数呢? 简单看了几种随机函数, 主要了解一下思想, 毕竟咱也不会真正的去写一个这样的函数.
计算机中的伪随机数
平方取中
由伟大的冯诺依曼前辈想出的. 其随机序列生成如下:
- 接收四位数输入 x
- s=x^2
- 若 s 不足8位, 左侧补0
- 取 s 的中间4位作为随机数y
- 将y 作为输入, 回到步骤1, 生成下一个随机数
是不是感觉很简单, 这样都能生成随机数? 为啥我没想到. 而且, 这样生成的数字符合统计学的均匀分布吗? 别说, 我还真写了一个小脚本, 跑了一下, 生成了一亿条数据, 只把生成的四位数字判断了一下. 结果其均匀分布效果不怎么样.
线性同余
其函数描述很简单: f(x)=(ax + b) % m. 随机序列的生成同理, 将上一次的输出作为下一次的输入. 很明显, 其中的 m 决定了序列生成随机数的最大值, 截断性线性同余法, 逆同余法 等是它的变种.
其他
还有线性反馈移位寄存器法、滞后斐波纳契法、马特塞特旋转法、WELL算法 等等.....
等等吧, 有很多生成随机数的方法, 不过具体怎么生成并实现我并不关心, 我只是想了解一下它大概是如何工作的, 能够如何生成随机数. 毕竟随机函数也用了这么久了, 稍微了解一下还是可以的. 上面这两种都是不安全的随机算法, 怎么说呢? 就是如果知道了当前的状态, 就可以通过计算, 得出之后所产生的随机数. 而一些安全的随机算法, 即使攻击者得到了大量的随机输出, 也很难预测未来的输出. 看了几种安全的随机算法, 都没看太明白, 水平有限...