linux内核随机数产生器
来源:互联网 发布:北京大土豆 知乎 编辑:程序博客网 时间:2024/05/19 12:14
Linux内核实现了一个随机数产生器,从理论上说这个随机数产生器产生的是真随机数。与标准C库中的rand(),srand()产生的伪随机数 不同,尽管伪随机数带有一定的随机特征,但这些数字序列并非统计意义上的随机数。也就是说它们是可重现的--只要每次使用相同的seed值,就能得到相同 的伪随机数列。通常通过使用time()的返回值来改变seed,以此得到不同的伪随机数序列,但time()返回值的结果并不是不确定的(可预测),也 就是这里仍然缺少一个不确定的噪声源。对于需要真随机数的程序,都不能允许使用伪随机数。
为了获得真正意义上的随机数,需要一个外部的噪声源。Linux内核找到了一个完美的噪声源产生者--就是使用计算机的人。我们在使用计算机时敲击 键盘的时间间隔,移动鼠标的距离与间隔,特定中断的时间间隔等等,这些对于计算机来讲都是属于非确定的和不可预测的。虽然计算机本身的行为完全由编程所控 制,但人对外设硬件的操作具有很大的不确定性,而这些不确定性可以通过驱动程序中注册的中断处理例程(ISR)获取。内核根据这些非确定性的设备事件维护 着一个熵池,池中的数据是完全随机的。当有新的设备事件到来,内核会估计新加入的数据的随机性,当我们从熵池中取出数据时,内核会减少熵的估计值。
上面这段代码是x86上用来处理某条中断线上注册的ISR例程的函数。这里我们感兴趣的地方是:如果ISR在注册期间指定了 SA_SAMPLE_RANDOM标志,在处理完action后,还要调用add_interrupt_randomness()这个函数,它使用中断间 隔时间为内核随机数产生器产生熵。内核就是在这里为熵池填充新数据的。
如果我们完全不操作计算机会如何呢?也就是作为噪声源的产生者,我们完全不去碰键盘,鼠标等外设,不让熵池获得新的数据,这个时候如果去熵池取数据内核会如何反应?
内核在每次从熵池中取数据后都会减少熵的估计值,如果熵估计值等于0了,内核此时可以拒绝用户对随机数的请求操作。
获取内核随机数有两种方法可以从熵池中获取内核随机数。一种是通过内核导出的随机数接口,另一种是通过特殊的设备文件/dev/random和/dev/urandom。下面分别讨论两种方法。
熵的输出接口该函数返回长度为nbytes字节的缓冲区buf,无论熵估计是否为0都将返回数据。使用这个函数时需要在内核空间。我们写一个小模块来测试一下。
Makefile如下:
编译之后加载模块,通过dmesg命令输出系统log最新的信息,可以看到我们的小模块输出了10个从内核熵池中得到的随机数。卸载模块后再次加载可以重新获取新的随机数,观察输出结果,与之前得到的随机数完全不一样。
这两个特殊设备都是字符型设备。我们可以在用户空间通过read系统调用读这两个设备文件以此获取随机数。这两个设备文件的区别在于:如果内核熵池的估计值为0时,
/dev/random将被阻塞,而/dev/urandom不会有这个限制。
同样,还可以用dd命令从/dev/urandom中获取指定字节数的随机值并写入文件中保存--如果你需要以文件的形式提供随机数的话。
dd if=/dev/urandom of = file count = 1 bs = bytes
关于内核随机数产生器的详细介绍,可参考Linux内核设计与实现第二版附录B。
- linux内核随机数产生器
- 内核随机数产生器
- Linux内核随机数产生器的设计与实现
- Linux内核随机数产生器的设计与实现
- 随机数产生器
- 随机数产生器
- 关于linux下的随机数产生器的简单原理
- NS2中的随机数产生器
- NS-2随机数产生器
- ns2中随机数产生器
- (转)随机数产生器RNG
- 随机数产生器RNG
- 随机数产生器RNG
- MSP430随机数产生器
- JVM随机数产生器
- C++随机数产生器
- NRF52832 RNG随机数产生器
- 随机数产生器RNG
- Java的(PO,VO,TO,BO,DAO,POJO)解释
- poi 获取excel中图片
- 达芬奇编解码引擎Codec Engine(CE)的理解
- 测量程序运行时间
- 舍弃浮躁, 50条重要的C++学习建议
- linux内核随机数产生器
- IOS_UIButton去掉系统的按下高亮置灰效果
- BIP语言简介
- NDK环境搭建
- opengl shader 使用札记
- 21-计算出两个日期相差的天数
- C# 概念
- CentOS 6.4 安装无线网卡驱动
- hdu2222 AC自动机入门 指针型模板