为什么$ RANDOM不是很随机?

时间:2014-05-13 19:27:18

标签: bash random

我一直在使用$RANDOM生成1到15之间的随机数,以便在两个系统之间产生一点抖动。例如:

sleep $(( RANDOM %= 15 ))

如果我每隔几分钟运行echo $(( RANDOM %= 15 )),则随机数似乎相当随机。但是,如果我每隔一分钟通过cron开始运行一个带有此调用的脚本,或者甚至只是每隔几秒钟回显一次随机数,随机性就会消失在我的Mac上,我最终会得到11和6之类的非随机值,依次交替,或8,4和2。不是很随机。

在我的一台Linux服务器(CentOS 6.5 x64)上,我添加了以下bash脚本,在第一对环路之后,只是一遍又一遍地输出13

#!/bin/bash
for ((n = 0; n < 100; n++))
do
  echo $(( RANDOM %= 15 ))
done

我的问题:

  1. 为什么会这样?我知道$RANDOM不适合加密,但为什么一般会产生随机数这么糟糕呢?
  2. 有没有其他简单的方法可以通过bash脚本获得更随机的数字(即使需要快速连续)?

2 个答案:

答案 0 :(得分:6)

分配给RANDOM设置种子值

RANDOM 是一个提供伪随机数的特殊变量。通过使用模运算符,您极大地限制了可能的值,并且通过分配给RANDOM,您将种子值更改为受限制集的某个成员,最终似乎在{{1} }。

以下给出了合理的分布:

13

使用for i in {1..100}; do echo $(( RANDOM % 15 )); done 代替%=,您正在设置种子值。别这么做。

答案 1 :(得分:2)

您可以使用以下命令生成1到15之间的高质量随机整数:

echo "$(od -An -N4 -tu4 /dev/urandom) % 15 + 1" | bc    

甚至更好

echo "$(od -An -N4 -tu4 /dev/random) % 15 + 1" | bc    

此外,您不应使用%=分配新种子,因为它会破坏收集的熵。

最后,100代真的不足以评估随机数发生器的质量。您至少应该生成一百万个值。

用于测试随机数生成器质量的几种便捷技术:

最佳压缩 - 0%

数据压缩或源编码是使用比未编码表示将使用的更少比特(或其他信息承载单元)通过使用特定编码方案来编码信息的过程。如果多次重复相同的数据结构,则短二进制表示可以代表长数据结构,从而减小压缩文件的大小。如果我们的随机数据是真正随机的,那么我们根本不应该看到任何压缩。

卡方分布 - 介于10%和90%之间

卡方检验是最常用的数据随机性检验,对伪随机序列生成器中的错误极为敏感。对于文件中的字节流计算卡方分布,并表示为绝对数和百分比,其表示真正随机序列超过计算值的频率。我们将百分比解释为被测序列被怀疑为非随机的程度。如果百分比大于90%或小于10%,则序列几乎肯定不是随机的。

算术平均值 - 127.5。在您的情况下为15/2

这只是将文件中所有字节相加并除以文件长度的结果。如果数据接近随机,则应为127.5左右。如果平均值偏离此值,则值始终为高或低。

Pi的蒙特卡罗值 - 3.14159265

每个连续的六个字节序列用作方形内的24位X和Y坐标。如果随机生成的点的距离小于刻在正方形内的圆的半径,则六字节序列被认为是命中。命中百分比可用于计算Pi的值。对于非常大的流,如果序列接近随机,则该值将接近Pi的正确值。

序列相关系数 - 0.0

此数量衡量文件中每个字节取决于前一个字节的程度。对于随机序列,这个值(可以是正数或负数)当然会接近于零。

来源:https://calomel.org/