红联Linux门户
Linux帮助

Linux随机数的产生

发布时间:2014-12-09 15:29:50来源:linux网站作者:chenxiancool

Linux内核采用熵描述数据的随机性,熵越大表示系统越混乱。计算机本身是可预测的系统,因此用计算机算法不可能产生真正的随机数。但由于机器中充满了噪声,而这些噪声又很难预测,没有规律可循,因此这些噪声可以作为随机数的产生源。Linux内核就是利用噪声来产生随机数的,它维持3个熵池(一级、二级和三级),而这些噪声课分为4类。如下:


1)I/O中断。内核调用add_interrupt_randomness()函数将设备两次中断的时间间隔作为噪声源将随机数据加入熵池,要使用设备的中断作为系统噪声,必须用SA_SAMPLE_RANDOM标志注册其中断服务程序。这样,每当设备发生中断时,中断系统会自动调用 add_interrupt_randomness()将熵加入熵池。


2)键盘:Add_keyboard_randomness()将按键的扫描码和两次按键之间的时间间隔作为噪声源;


3)鼠标:而add_mouse_randomness()则利用鼠标位置和连续两次鼠标中断时间间隔填充熵池;


4)硬盘:最后 add_disk_randomness()函数则以连续两次磁盘操作之间的间隔产生随机数。


为跟踪熵池中数据的随机性,内核在将数据加入池的时候将估算数据的随机性,这个过程称作熵估算。熵估算值描述池中包含的随机数位数,其值越大表示池中数据的随机性越好。上面的函数最终都是通过调用 add_timer_randomness()函数将熵加入熵池的。Add_timer_randomness()首先估算所加数据的熵,再调用 batch_entropy_store()函数将数据加入熵池。为了避免中断的延迟过长影响系统性能,batch_entropy_store()并不直接将熵加入熵池,而是将其加入队列中。当队列长度达到一定长度后,由keventd内核线程通过调用batch_entropy_process()函数将队列中的熵加入池中。Batch_entropy_process()函数枚举队列中的每个熵,对每个熵调用 add_entropy_words()函数将其加入熵池,但它并不更新熵池的熵估算值。为此,batch_entropy_process()对每个熵调用完add_entropy_words()后,立刻调用credit_entropy_store()函数更新熵估算值。