Bash 为什么$RANDOM不是很随机?

Bash 为什么$RANDOM不是很随机?,bash,random,Bash,Random,为了在两个系统之间产生一点抖动,我一直在使用生成一个1-15之间的随机数。例如: sleep $(( RANDOM %= 15 )) 如果我每隔几分钟运行一次echo$((RANDOM%=15)),看起来随机数是相当随机的。但是如果我开始通过cron每分钟运行一个带有这个调用的脚本,甚至每隔几秒钟就回显一次随机数,那么随机性在我的Mac上就消失了,我最终得到的不是那么随机的值,比如11和6,交替,或者8,4和2。不是很随意 在我的一台linux服务器(CentOS 6.5 x64)上,我添加了

为了在两个系统之间产生一点抖动,我一直在使用生成一个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
#/bin/bash
对于((n=0;n<100;n++)
做
echo$((随机%=15))
完成
我的问题是:

  • 为什么会这样?我知道,
    $RANDOM
    不适合加密,但为什么它在一般情况下生成随机数时如此糟糕
  • 有没有其他简单的方法可以通过bash脚本获得更多的随机数(即使需要快速连续)
  • 将种子值指定给随机集 RANDOM是一个提供伪随机数的特殊变量。通过使用模运算符,您极大地限制了可能的值,通过将种子值赋给RANDOM,您将种子值更改为受限制集的某个成员,这似乎最终解决了
    13

    以下是我的合理分配:

    for i in {1..100}; do echo $(( RANDOM % 15 )); done
    

    通过使用
    %=
    而不仅仅是
    %
    ,可以设置种子值。不要这样做。

    您可以使用以下命令生成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左右。如果平均值偏离该值,则值始终为高或低

    圆周率的蒙特卡罗值——3.14159265

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

    序列相关系数--0.0

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


    来源:

    为什么要分配给RANDOM?通常,获得真正的$RANDOM的最佳方法是先“播种”你的值。比如,将它乘以当前时间(以毫秒为单位),或者别的什么。这样会更加随机和独特。@CodeGnome-我不是。。。更新了上面的示例以反映我实际正在做的事情,很抱歉:D@geerlingguy您认为
    %=
    操作符是做什么的?(提示:它的一部分是
    =
    )不要不断地给随机数生成器添加种子。种子一次,然后对它进行数千次采样以初始化它,然后继续采样以供使用。我认为这并不能回答问题,这就是为什么OP使用
    $RANDOM
    失败的原因,不知道如何做得比
    $RANDOM
    更好。OP的第二个问题是关于另一种方法。可能值得注意的是,$RANDOM提供了一个介于
    0…32767
    之间的伪随机数,并且由于它不能被15整除,所以取输出mod 15不会在0…14中产生均匀分布。尽管如此,这显然无关紧要,因为当需要任何精度时,不应使用
    $RANDOM