我一直在使用$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
我的问题:
$RANDOM
不适合加密,但为什么一般会产生随机数这么糟糕呢?答案 0 :(得分:6)
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
此数量衡量文件中每个字节取决于前一个字节的程度。对于随机序列,这个值(可以是正数或负数)当然会接近于零。