简体   繁体   English

如何在bash中获得0到999999999之间的随机(/ dev / random)数字?

[英]How can I get a random (/dev/random) number between 0 and 999999999 in bash?

For example, 例如,

echo "$(( ($(od -An -N2 -i /dev/random) )%(1000-0+1) ))"

can be used. 可以使用。 But it doesn't scale for bigger numbers. 但它不适用于更大的数字。

How can I get a random (/dev/random) number between 0 and 999999999 in bash? 如何在bash中获得0到999999999之间的随机(/ dev / random)数字?

I'd use: 我用的是:

shuf -i0-999999999 -n1

although there is no guarantee that shuf uses /dev/random . 虽然不能保证shuf使用/dev/random With GNU shuf you can specify --random-source=/dev/random if you really want to. 使用GNU shuf ,如果你真的想要,你可以指定--random-source=/dev/random

IIRC, FreeBSD (and probably Mac OS X) call this utility shuffle , and it takes slightly different arguments ( shuffle -n1000000000 -p1 ). IIRC,FreeBSD(可能还有Mac OS X)调用这个实用程序shuffle ,它需要稍微不同的参数( shuffle -n1000000000 -p1 )。

If you really want to use /dev/random directly, you can generate a four-byte number by using od -An -N4 -tu4 but remember that there is a bias generated by using %1000000000 , since 2 32 is not divisible by 1000000000 . 如果你真的想直接使用/dev/random ,你可以使用od -An -N4 -tu4生成一个四字节数字,但要记住使用%1000000000产生偏差,因为2 32不能被1000000000整除。 To correct for that, in the particular case of generating random numbers in the range 0-999999999 , you need to reject the four-byte random number if it is greater than or equal to 4000000000 . 要纠正的是,在该范围内产生随机数的具体情况0-999999999 ,你需要拒绝的四字节的随机数,如果大于或等于4000000000

Explenation Explenation

The key to doing this using /dev/random is thinking about what produces a uniform distribution. 使用/dev/random执行此操作的关键是考虑产生均匀分布的原因。 /dev/random does, but doing /dev/random确实如此

 od -An -N2 -i /dev/random

Provides a 2-byte output, which is uniform over 0...2 16 -1 or 0...65535. 提供2字节输出,在0 ... 2 16 -1或0 ... 65535之间均匀输出。 But obviously not uniform over 0...99999. 但显然不是统一超过0 ... 99999。

Taking it mod 1000, will change the output to 0...999, but the distribution still won't be uniform over it. 取其mod 1000,将输出更改为0 ... 999,但分布仍然不均匀。

Solution

Let's say we have a pseudo-random generator that produces 0,1,2,3,4, but we want one that produces 0,1. 假设我们有一个产生0,1,2,3,4的伪随机生成器,但我们想要一个产生0,1的生成器。 We just ignore any output 2,3,4 and keep outputs 0,1 which by definition must still be pseudo-random. 我们忽略任何输出2,3,4并保持输出0,1,根据定义它们仍然必须是伪随机的。

So, you can do something like this. 所以,你可以做这样的事情。

To get a single digit you can do something like this 要获得一个数字,你可以做这样的事情

while :; do ran=$(echo $(od -An -N1 -i /dev/random)) && [[ $ran -lt 250 ]] && \
echo ${ran: -1} && break; done

since the distribution of the least significant digit between 0...249 is uniform. 因为0 ... 249之间的最低有效位的分布是均匀的。

Then to build a 9 digit random number, just do something like 然后建立一个9位数的随机数,就像做一样

#!/bin/bash

digit() {
  while :; do ran=$(echo $(od -An -N1 -i /dev/random)) && [[ $ran -lt 250 ]] && \
  echo ${ran: -1} && break; done
}

for ((i=0; i<9; i++)) {
  num+=$(digit)
}

echo $num

你可以使用awk ,它几乎可以在任何类似UNIX的盒子上使用:

awk 'BEGIN{print int(rand()*999999999)}'
 cat /dev/random | tr -cd 0-9 | dd bs=1 count=9

Cat random data from /dev/random , delete all except 0 , 1 , ... 9 ; 猫随机数据从/dev/random ,删除所有除01 ,... 9 ; then wait only for 9 digits with dd. 然后用dd等待9位数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM