bash中的优化随机数生成

bash中的优化随机数生成,bash,random,Bash,Random,我想使用bash生成很多介于0和1之间的整数 我尝试了shuf,但生成速度非常慢。还有其他生成数字的方法吗?tr-dc'01'

我想使用bash生成很多介于0和1之间的整数


我尝试了
shuf
,但生成速度非常慢。还有其他生成数字的方法吗?

tr-dc'01'
是一种快速而肮脏的方法


如果您在OSX上,
tr
可能会有点奇怪,因此您可以使用perl来代替:
perl-pe'tr/01//dc'
这将输出无限字节流,以二进制形式编写,并用空格分隔:

cat /dev/urandom | xxd -b | cut -d" " -f 2-7 | tr "\n" " "
例如:

10100010 10001101 10101110 11111000 10011001 01111011 11001010 00011010 11101001 01111101 10100111 00111011 10100110 01010110 11101110 01000011 00101011 10111000 01010110 10011101 01000011 00000010 10100001 11000110 11101100 11001011 10011100 10010001 01000111 01000010 01001011 11001101 11000111 11110111 00101011 00111011 10110000 01110101 01001111 01101000 01100000 11011101 11111111 11110001 10001011 11100001 11100110 10101100 11011001 11010100 10011010 00010001 00111001 01011010 00100101 00100100 00000101 10101010 00001011 10101101 11000001 10001111 10010111 01000111 11011000 01111011 10010110 00111100 11010000 11110000 11111011 00000110 00011011 11110110 00011011 11000111 11101100 11111001 10000110 11011101 01000000 00010000 00111111 11111011 01001101 10001001 00000010 10010000 00000001 10010101 11001011 00001101 00101110 01010101 11110101 10111011 01011100 00110111 10001001 00100100 01111001 01101101 10011011 00100001 01101101 01001111 01101000 00100001 10100011 00011000 01000001 00100100 10001101 10110110 11111000 01110111 10110111 11001000 00101000 01101000 01001100 10000001 11011000 11101110 11001010 10001101 00010011^C
如果您不需要字节之间的空格(谢谢@Chris):

只是为了好玩--

本机bash函数,用于打印指定数量的随机位,从
$random
的最小可能计算数中提取:

randbits() {
  local x x_bits num_bits

  num_bits=$1

  while (( num_bits > 0 )); do
    x=$RANDOM
    x_bits="$(( x % 2 ))$(( x / 2 % 2 ))$(( x / 4 % 2 ))$(( x / 8 % 2 ))$(( x / 16 % 2 ))$(( x / 32 % 2 ))$(( x / 64 % 2 ))$(( x / 128 % 2 ))$(( x / 256 % 2 ))$(( x / 512 % 2 ))$(( x / 1024 % 2 ))$(( x / 2048 % 2 ))$(( x / 4096 % 2))$(( x / 8192 % 2 ))$(( x / 16384 % 2 ))"
    if (( ${#x_bits} < $num_bits )); then
      printf '%s' "$x_bits"
      (( num_bits -= ${#x_bits} ))
    else
      printf '%s' "${x_bits:0:num_bits}"
      break
    fi
  done
  printf '\n'
}


因为它使用了
$RANDOM
,所以可以通过在调用它之前将种子值分配给
$RANDOM
,使其行为变得可复制。如果您希望能够在使用“随机”输入的软件中重现错误,这将非常方便。

由于问题要求在
1和0之间的整数
,因此有一种非常随机且非常快速的方法。一个好的一行肯定:

echo "0.$(printf $(date +'%N') | md5sum | tr -d '[:alpha:][:punct:]')"
当在
for
循环中抛出10次迭代时,此命令将为您提供类似的输出:

0.97238535471032972041395  
0.8642459339189067551494  
0.18109959700829495487820  
0.39135471514800072505703651  
0.624084503017958530984255  
0.41997456791539740171  
0.689027289676627803  
0.22698852059605560195614  
0.037745437519184791498537  
0.428629619193662260133
011101001110  
001110011011  
0010100010111111  
0000001101101001111011111111  
1110101100  
00010110100  
1100101101110010  
101100110101100  
1100010100  
0000111101100010001001
如果您需要打印1和0的随机字符串,正如其他人所假设的那样,您可以对命令进行如下细微更改:

printf $(date +'%N') | sha512sum | tr -d '[2-9][:alpha:][:punct:]'
这将产生一个随机0和1的输出,类似于在10次迭代中抛出for循环时的输出:

0.97238535471032972041395  
0.8642459339189067551494  
0.18109959700829495487820  
0.39135471514800072505703651  
0.624084503017958530984255  
0.41997456791539740171  
0.689027289676627803  
0.22698852059605560195614  
0.037745437519184791498537  
0.428629619193662260133
011101001110  
001110011011  
0010100010111111  
0000001101101001111011111111  
1110101100  
00010110100  
1100101101110010  
101100110101100  
1100010100  
0000111101100010001001
据我所知,从我在网上发现的情况来看,这是我们在bash中能得到的最接近真实随机性的结果。我甚至做了一个骰子游戏(骰子有10个边0-9)来测试随机性,使用这种方法生成一个从
0
9
的单个数字。在100次掷骰子中,每一方几乎完美地落下10次。在1000次投掷中,每一方击出大约890-1100次。投掷1000次后,侧面落地的变化不大。所以您可以非常肯定,这种方法非常理想,至少对于生成伪随机数的bash工具来说是如此

如果你只需要一个绝对的、让你头脑发热的、荒谬的随机性,那么简单的
md5sum
checksum命令本身可以被复合很多次,而且速度仍然非常快。例如:

printf $(date +'%N') | md5sum | md5sum | md5sum | tr -d '[:punct:][:space:]'
这将有一个不太随机的数字,从打印
date
命令的纳秒选项获得,通过管道输送到
md5sum
。然后,md5散列通过管道传输到
md5sum
,然后最后一次将“该”散列发送到
md5sum
。输出是一个完全随机的散列,您可以使用诸如
awk
sed
grep
tr
等工具来控制要打印的内容


希望这有帮助。

“0和1之间的整数”,你是指0和1的随机字符串,对吗?还有,谷歌给了我$RANDOM,你看到/尝试过吗?你到底用了什么
shuf
本身不会生成任何内容。“0到1之间的整数”集为空,除非这些端点包含在内。您所说的“未成功”是什么意思?它没有为你生成随机数?你用的是哪个版本的bash?@ArthurChaloin,…嗯?你到底是如何使用总是给你1的
$RANDOM
$((随机%2))
应该是1,几乎一半的时间。这就浪费了你的大部分熵——很快就会耗尽池中的能量(之后会得到更少的随机数)。@CharlesDuffy
/dev/Uradom
/dev/RANDOM
使用CSPRNG,而实际上你必须长期使用随机数,长时间消耗可用熵。看见这显然不理想,但实际上不太可能造成问题。
/dev/random
阻塞,因为熵池不被认为太随机,这是一个非常真实和常见的现象——从
/dev/uradom
读取会消耗相同的池,尽管它为空时不会阻塞,因此,您正在为需要强伪随机内容(密钥生成&c)挂起的应用程序进行设置。是的,此命令输出的数字比我的少,但可能已经足够了。你可以得到我的投票,因为它更短,更容易记住。@这就是克里斯使用
uradom
的原因。你可以把它缩短一点,去掉空格:
xxd-b
。我喜欢你回答的效率,谢谢。这是品味的问题,但我认为