dev/urandom
当使用head
或读取, 时dd
,当然期望输出始终是随机且不同的。
UNIX 在底层是如何处理这个问题的?文件在读取时是否自然被截断,或者文件实际上是对称密码或等效密码的接口,因此“读取”实际上是执行密码的行为。
答案1
/dev/urandom
是字符设备,而不是常规文件。打开它提供了一个驱动程序的接口,通常在内核中,它处理读取;每次程序读取时/dev/urandom
,都会调用驱动程序,驱动程序确定如何提供适当的内容(与任何其他字符设备相同 - /dev/null
,/dev/zero
...)。
在 Linux 上,这是在drivers/char/random.c
。它维护一个“熵池”,从各种随机数据源中获取种子,并在读取时使用 ChaCha 流密码处理池数据以构造要返回的数据。
答案2
/dev/urandom
不是“常规文件”(是的,这是 POSIX 命名),它是一个设备。就像 /dev/ 上的大多数“文件”一样,所以那里有很多神奇的行为。
- 你有
/dev/null
,无论你写多少,它都无法填满 - 你有random/urandom/srandom,每次随机提供不同的数据
- 您(和同事)有
/dev/tty
与终端交互的地方 /dev/full
对于任何写入尝试,您总是返回“设备上没有剩余空间”- 你有
/dev/zero
它返回无限的 nul 字节集
还有很多。
这些文件实际上是与内核模块交互的接口。因此,当您“读取”它时,它实际上正在执行一个函数,该函数被要求读取程序(head、dd等)请求的尽可能多的字节(/dev/urandom
是一个特点设备)。然后,该函数在内部处理它(基于几个熵池)以填充该缓冲区(在本例中,以便您获得伪随机内容)。