信息熵与随机数
在程序开发中,我们经常会用到随机数,确保某个事件发生是具有随机性,不可预测性的。而事实是随机性却不是那么随机,我们大多用的都是伪随机数。那什么才是真随机数呢?
信息熵
什么是熵?在物理学中,熵(entropy)是一个描述系统混乱程度的物理量,熵越大说明系统越无序、越混乱,不确定性越大。例如:一杯水,所有的水分子都是聚集在一起叫低熵,把这杯水静置一段时间,水分子扩散出处,弥漫到整个房间,这个过程叫熵增。整个宇宙事实上都在做熵增的运动。而人可能喜欢有序,尽量把物体放置整齐,垃圾分类处理,减少熵的增加,让世界整齐有序活动,喜欢可预测可掌控生活。
那么什么是信息熵?信息熵是描述信息的复杂程度,信息克服了多大的不确定性。例如:abcdefgh… 我们很容易推测到后面应该是ijklmn,例如数列: 1 1 2 3 5 8 13… 我们也容易知道后面的数是21。这些都是可预测性的规律,信息熵就比较低。同样的一本书,英文版本的书信息熵比较低,而中文版的信息熵比较高。因为英文有大量介词,定冠词等字母。即时去掉一两个也同样能理解这句话的意思,但是同样的一句话中文表达的信息量就远大于英文。古代的文言文信息熵就远大于今天的汉语,因为文言文的信息熵比较高,这也是省了不少竹简呀!同样高效的语言文本,最高效的信息熵应该是乱码,杂乱无章,没任何规律可循。列如:服务器密钥文件,比特币、以太坊私钥的生成都已经克服了很大的不确定性,足够混乱,至少现在看来是安全的。
随机数
在Linux内核中采用熵来描述数据的随机性。为了能产生足够高效随机数,Linux系统维护了一个专门用于收集噪声的熵池(entropy pool),熵池的信息来自外界的熵信息 如:设备驱动的噪音,鼠标点击的声音,设备风扇运作的噪音。将这些噪声收集起来被用于产生真正的随机数。如果熵池中没有足够的噪音资源,就需要等待熵池的收集。只要设备的物理混乱程度越大,熵增就越快,熵池的信息越饱和,随机性的效率就越高。
/dev/random 是 Linux/Unix 操作系统中的一个设备文件,用来作为随机数发生器/伪随机数发生器。它允许程序访问来自设备驱动程序或其它来源的背景噪声,Linux是第一个以背景噪声产生真正的随机数的实现。这种设计使得/dev/random是真正的随机数发生器,提供了最大可能的随机数据熵。因为它是真正以熵池的背景噪音为种子产生随机数,所以在调用时可能会有堵塞,需要等待熵池有足够多的熵信息。另外一种 /dev/urandom ,它是非阻塞的发生器,它会重复使用熵池中的信息产生伪随机数。这种随机数的生成一般运用在密钥强度要求不是太高的地方。另外还有一些常见的随机数算法有线性同余法(Linear Congruential Generator)、梅森旋转法(Mersenne twister)等。其中线性同余的随机性相对较差点,而梅森旋转法的随机性较好,ruby、python的底层实现采用了这种随机数算法。
补充:为什么不直接使用种子作随机数?
- 速度问题:收集种子通常很耗时
- 熵(不确定性):种子的熵通常比较低,但不管其熵如何,伪随机序列发生器都能产生统计性好的序列
来源:CSDN
作者:JixinX
链接:https://blog.csdn.net/Jixinxxx/article/details/103808777