利用/dev/urandom文件创建随机数

1. 基本介绍

/dev/random/dev/urandom是Linux系统中提供的随机伪设备,这两个设备的任务,是提供永不为空的随机字节数据流。很多解密程序与安全应用程序(如SSH Keys,SSL Keys等)需要它们提供的随机数据流。

这两个文件记录Linux下的熵池,所谓熵池就是当前系统下的环境噪音,描述了一个系统的混乱程度,环境噪音由这几个方面组成,如内存的使用,文件的使用量,不同类型的进程数量等等,刚开机的时候系统噪音会较小。

这两个设备的差异在于:/dev/randomrandom pool依赖于系统中断,因此在系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用, /dev/random设备可以保证数据的随机性。/dev/urandom不依赖系统的中断,也就不会造成进程忙等待,但是数据的随机性也不高。

2. 获取/dev/urandom和/dev/random中的值

1
2
3
4
# dd count=1 ibs=1024 if=/dev/random >/dev/null
0+1 records in
0+1 records out
73 bytes (73 B) copied, 7.948e-05 s, 918 kB/s
1
2
3
4
# dd count=1 ibs=1024 if=/dev/urandom >/dev/null
1+0 records in
2+0 records out
1024 bytes (1.0 kB) copied, 5.7645e-05 s, 17.8 MB/s

可以看见/dev/urandom生成随机数的速度要快很多,一般就使用/dev/urandom获取随机数。

3. 在Python中如何生成随机数

我们首先了解一个知识点–伪随机数发生器。用于在系统需要随机数的时候,通过一系列种子值计算出来的伪随机数。因为生成一个真正意义上的“随机数”对于计算机来说是不可能的,伪随机数也只是尽可能地接近其应具有的随机性,但是因为有“种子值”,所以伪随机数在一定程度上是可控可预测的。

通过程序得到的随机数无论什么算法都一定是通过递推公式得到的序列,这本身就违反了随机的定义,所以它们都不是真正的随机数。伪随机数中一个很重要的概念就是“种子”,种子决定了随机数的固定序列,例如在C语言rand函数得到的序列每次都是相同的,如果想得到不同序列需要调用srand设置种子;同理在Java中new Random(1)的构造函数参数来设置种子 。

我们知道文件读取出来的是二进制数据,这个时候想转为随机数还需要一个模块–struct

python中的struct主要是用来处理C结构数据的,读入时先转换为Python的字符串类型,然后再转换为Python的结构化类型,比如元组(tuple)啥的~。一般输入的渠道来源于文件或者网络的二进制流。

struct模块中最重要的三个函数是pack(), unpack(), calcsize()

1
2
3
4
5
6
7
8
#  按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
pack(fmt, v1, v2, ...)

# 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
unpack(fmt, string)

# 计算给定的格式(fmt)占用多少字节的内存
calcsize(fmt)
1
2
3
4
5
6
7
8
9
10
11
12
13
def urandom_seed():

seed_num = None

with open(r'/dev/urandom', r'rb') as f:
# 我们获取四个字节 字符串 将其转为 32位的大端无符号整型数据
seed_num = struct.unpack(f'!I', f.read(4))[0]
random.seed(seed_num)

return seed_num

In [299]: urandom_seed()
Out[299]: 3238305502

seed() 方法改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数。

参考阅读:

/dev/random

关于 /dev/urandom 的流言终结

Linux系统产生随机数/dev/random 和 /dev/urandom

Python 中的 pack 和 unpack

Python标准库笔记(6) — struct模块

How to get numbers from /dev/random using Python?

字节顺序

Python seed() 函数

Python3标准库:random伪随机数生成器

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!