生成特定范围内的随机数

Bow*_*ark 107 command-line shell random command

在谷歌搜索了一下之后,我找不到一种简单的方法来使用 shell 命令生成一个包含在特定范围内的随机十进制整数,即介于最小值和最大值之间。

我读过/dev/random,/dev/urandom$RANDOM,但这些都不能满足我的需要。

有没有其他有用的命令,或者使用以前数据的方法?

cuo*_*glm 176

您可以shuf从 GNU coreutils尝试:

shuf -i 1-100 -n 1
Run Code Online (Sandbox Code Playgroud)

  • `shuf -i 1000-9999 -n 256 -o file_name.txt` - 生成从 1000 到 9999 的*唯一* 256 个数字,并将它们保存到名为 `file_name.txt` 的文件中。 (2认同)

Sté*_*las 59

在 POSIX 工具箱中,您可以使用awk

awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'
Run Code Online (Sandbox Code Playgroud)

千万不能使用它作为源生成口令或例如秘密数据,与大多数awk实现中,数量可以很容易地根据该命令运行的时间猜测。

对于许多awk实现,该命令在同一秒内运行两次通常会给您相同的输出。

  • 是按时间来的吗?因为我在连续 2 次运行中得到了相同的值...... (2认同)

小智 37

在 BSD 和 OSX 上,您可以使用jot返回-r从间隔min到的单个随机 ( ) 数max,包括。

$ min=5
$ max=10
$ jot -r 1 $min $max
Run Code Online (Sandbox Code Playgroud)

分布问题

不幸的是,随机生成数字的范围和分布受到 jot 内部使用双精度浮点运算和 printf(3) 输出格式这一事实的影响,这会导致舍入和截断问题。因此,间隔的minmax生成频率较低,如下所示:

$ jot -r 100000 5 10 | sort -n | uniq -c
9918  5
20176 6
20006 7
20083 8
19879 9
9938  10
Run Code Online (Sandbox Code Playgroud)

在 OS X 10.11 (El Capitan) 上,这似乎已得到修复:

$ jot -r 100000 5 10 | sort -n | uniq -c
16692 5
16550 6
16856 7
16579 8
16714 9
16609 10  
Run Code Online (Sandbox Code Playgroud)

和...

$ jot -r 1000000 1 10 | sort -n | uniq -c
100430 1
99965 2
99982 3
99796 4
100444 5
99853 6
99835 7
100397 8
99588 9
99710 10
Run Code Online (Sandbox Code Playgroud)

解决分布问题

对于旧版本的 OS X,幸运的是有几种解决方法。一种是使用 printf(3) 整数转换。唯一需要注意的是,间隔最大值现在变为max+1. 通过使用整数格式,我们可以在整个区间内得到公平的分布:

$ jot -w %i -r 100000 5 11 | sort -n | uniq -c
16756 5
16571 6
16744 7
16605 8
16683 9
16641 10
Run Code Online (Sandbox Code Playgroud)

完美的解决方案

最后,为了使用变通方法公平地掷骰子,我们有:

$ min=5
$ max_plus1=11  # 10 + 1
$ jot -w %i -r 1 $min $max_plus1
Run Code Online (Sandbox Code Playgroud)

额外的作业

有关血腥的数学和格式详细信息以及更多示例,请参阅jot(1)


jof*_*fel 18

$RANDOM变量通常不会产生良好的随机值的好方法。输出/dev/[u]random也需要先转换。

更简单的方法是使用更高级的语言,例如 python:

要生成 5 到 10 (5<=N<=10) 之间的随机整数变量,请使用

python -c "import random; print random.randint(5,10)"
Run Code Online (Sandbox Code Playgroud)

不要将此用于加密应用程序。


小智 15

您可以通过以下方式获取随机数 urandom

head -200 /dev/urandom | cksum

输出:

3310670062 52870

检索上述数字的一部分。

head -200 /dev/urandom | cksum | cut -f1 -d " "

然后输出是

3310670062

  • `head -200`(或其 POSIX 等价物 `head -n 100`)返回 `/dev/urandom` 的前 200 *行*。`/dev/urandom` 不是文本文件,该命令可以从 200 个字节(所有 0x0a 字节,ASCII 中的 LF)返回到无穷大(如果 0xa 字节碰巧永远不会返回),但 45k 和 55k 之间的值是最多的可能。cksum 返回一个 32 位数字,因此从`/dev/urandom` 获取超过 4 个字节是没有意义的。 (3认同)

jof*_*fel 12

要生成 5 到 10(包括两者)之间的随机整数变量,请使用

echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))
Run Code Online (Sandbox Code Playgroud)

% 作为模运算符工作。

可能有更好的方法将随机变量$RANDOM转换为特定范围。不要将它用于加密应用程序,或者在您需要真实的、均等分布的随机变量的情况下(例如用于模拟)。

  • 在许多确实有 $RANDOM 的 shell 实现中(尤其是较旧的,尤其是 bash),这不是很随机。在大多数壳中,该数字在 0 到 65535 之间,因此任何宽度不是 2 的幂的范围都会有概率分布差异。(在这种情况下,数字 5 到 8 的概率为 10923/65536,而数字 9 和 10 的概率为 10922/65536)。范围越大,差异越大。 (5认同)

小智 7

# echo $(( $RANDOM % 256 )) 将在现代 *sh 方言中产生 0-255 之间的“随机”数字。


小智 6

也许UUID(在 Linux 上)可用于检索随机数

$ cat /proc/sys/kernel/random/uuid
cdd52826-327d-4355-9737-895f58ad11b4
Run Code Online (Sandbox Code Playgroud)

获取70和之间的随机数100

POSIXLY_CORRECT=1 awk -F - '{print(("0x"$1) % 30 + 70)}
   ' /proc/sys/kernel/random/uuid
Run Code Online (Sandbox Code Playgroud)


小智 6

cat /dev/urandom | tr -dc 'a-fA-F0-9' | fold -w 8 | head -n 1
Run Code Online (Sandbox Code Playgroud)

这将生成一个 8 位长的十六进制数。


小智 5

分布良好:

for (( i = 1 ; i <= 100000 ; i++ )) do echo $(( RANDOM % (20 - 10 + 1 ) + 10 )) ; done | sort -n | uniq -c
Run Code Online (Sandbox Code Playgroud)

给出:

  count value

   9183 10
   9109 11
   8915 12
   9037 13
   9100 14
   9138 15
   9125 16
   9261 17
   9088 18
   8996 19
   9048 20
Run Code Online (Sandbox Code Playgroud)