Python·为什么说random模块不安全
在Python文档关于Random模块的地方有如下警告,这是为什么呢


伪随机数的概念
真正意义上的随机数(或者随机事件)在某次产生过程中是按照实验过程中表现的分布概率随机产生的,其结果是不可预测的,是不可见的。而计算机中的随机函数是按照一定算法模拟产生的,其结果是确定的,是可见的。我们可以这样认为这个可预见的结果其出现的概率是100%。所以用计算机随机函数所产生的“随机数”并不随机,是伪随机数。

Python层面分析
这里我们生成了一个包含10个随机2位整数的列表
每次运行得出来的结果肯定是不一样的,这是为什么呢,我们来一步步分析原理
我们按住Ctrl点击random(这里用的Pycharm,用IDLE的就手动跳转吧hhh),跳到random的定义处看看
可以看到如下所示的代码块,熟悉类的朋友一眼就能看出来,_inst就是Random这个类的实例
然后将类方法导出为模块级函数,方便用户使用
了解一个类,那么肯定先去看看他的构造函数里干了些什么,跳到Random处看看
可以看到只有一个类方法调用和一个类变量的初始化,那么我们自然是先去看看这个类方法干了些什么
读注释你应该也能看明白这个方法是干什么的,用来改变随机数生成器的种子
那么我们继续分析它的流程
一个if判断version和a的类型,显而易见这俩条件都不满足,直接走到下面
调用了 super().seed(a) ,回到前面我们我可以发现这个类继承了
_random.Random,那么我们继续跳到这个类的seed方法看看
看到这里有些人会觉得很奇怪,哎为什么这个方法里啥都没写,因为这里是c语言写的
现在可以选择读注释,当然我们知道,解释器是CPython,而且他是开源的!那么继续往前冲,看看CPython的源码这里是怎么写的
Github指路: https://github.com/python/cpython

CPython分析
找到 ../Modules/_randommodule.c
读注释我们可以知道他用的随机数生成器是 Mersenne Twister
然后找到如下函数,可以知道,当参数传参为None时,调用了
random_seed_time_pid
这里就可以知道他是通过获取系统当前时间和进程ID来初始化随机数生成器的,用当前时间来初始化随机数生成器也是很常用的一种方式

源码的分析就到这里了,从Python层面到底层CPython,虽然过程很麻烦,但这样能让我们更好的了解他,这也是学习的一个很好的方式
整理一下,当你直接使用random.randint时,Random类内部默认调用seed(None),然后使用系统当前时间和pid来初始化随机数生成器,这样当你每一次启动程序时产生的随机数都不一样了

安全性问题分析
终于讲到正题了,讲了这么多,应该已经有朋友明白了,一旦逆向分析者知道了seed,那么规律不就显而易见了吗
是这样的,我们实践操作一样,现在你会发现
每次重启程序,得到的结果都是一样的了
参考资料
Python文档 - random模块
https://docs.python.org/zh-cn/3/library/random.html
CPython源码
https://github.com/python/cpython
关于安全性:为什么Python中random.random()不安全?
https://www.codenong.com/54672594/
随机数:真随机数和伪随机数
https://blog.csdn.net/czc1997/article/details/78167705

看了那么多为什么还不三连!?
看了那么多为什么还不三连!?
看了那么多为什么还不三连!?