如何在 bash 命令中生成更好的随机数 Line

中随机数的生成 bash 使用似乎很容易做到 $RANDOM 变量,但变量真的那么随机吗? 找出可能阻止您生成高质量随机数的原因,等等!

终端中的随机数

在 Bash 中生成随机数似乎很简单:

但是这个数字真的是随机的吗?

正如我们所见,并非如此。 Bash 中的随机数生成器依赖于种子(传递给随机数生成器函数的值),只要种子相同,它将始终生成与随机数生成器相同的随机数序列。 example 显示先前的输出。

我们可以通过设置初始值来初始化随机数生成器 RANDOM 变量到所需的初始值。 那么也许我们可以提供一个随机数作为随机生成器的种子?

它似乎有点工作,每次我们想要生成一个随机数时,我们都会用一个随机生成的数字预置随机数生成器。 但是我们所做的只是暂时自欺欺人; 我们只是创建了一个额外的深度层,但结果几乎相同; 这些数字不是随机的,可能会受到上面提供的固定种子的影响。

这个问题被称为“随机熵”生成问题。 我们可以产生的熵越多,我们的随机数就越好。 这个特殊问题不仅限于 Bash,它存在于所有尝试生成随机数的基本计算机系统中。 因此,随机从来都不是真正随机的。 其他一些随机系统用于 example 鼠标移动和击键等半随机输入相结合,增加了随机熵池的复杂性。

那么我们如何才能生成一个“足够好”的随机数来真正随机命名呢?

为此,我们需要一些真正或几乎真正随机的东西作为来源和种子。 我们可以考虑使用今天的日期,但这不是很随机,想一想。 自 00:00:00 UTC 1970 年 1 月 1 日以来的秒数(通常称为“纪元” Linux 界)? 也许吧,但你所需要的只是某处的日志文件,你可以重建时代。

更好的解决方案是使用纳秒精度计时器的最低有效位:

更好的随机数种子生成器

原则上,即使这样也不是完美的。 根据本文的标题,它可能属于“更好的随机数生成”的标题,但根据定义,熵并不完美。 让我们仔细看看这个。

在示例中,我们采用字节 4 到 9 或纪元时间编号 6,如下所示 date +%N 并作为 subshel​​l 启动的结果输出 $(...). 这意味着我们的最小种子是 0,我们的最大种子是 999999。这只是 100 万个数字的范围。

原则上,这个系统仍然可以被“破解”:一个人可以简单地遍历所有这 100 万个数字并获取从中生成的随机数序列。 对于加密密钥生成来说,这肯定是一个非常糟糕的解决方案,因为 example!

如果我们选择的数字越少,发生这种情况的风险就越大。 如果我们选择更多,风险就会变小,但“随机种子”也会变得不那么随机。 这可以通过包括纪元以来的秒数来举例说明:

使用秒数生成随机熵的问题

我们可以看到时间在流逝! 注意开头的 6 > 7 > 8 等等。

对于标准随机数生成目的,对于 example 在根据提供给它的随机种子改变其测试方法的测试软件中,基于纳秒的解决方案就足够了。 对于可能需要更高质量随机数的其他解决方案,可能需要基于外部硬件的解决方案。

真正的随机数生成并不是一件简单的事情。 有一些基于硬件的解决方案可以接近或实现真正的随机熵和/或随机数生成。 特别是不仅仅是基于硬件的设备可能是生成完美随机数的关键。