Después de buscar un poco en Google, no pude encontrar una manera simple de usar un comando de shell para generar un número entero decimal aleatorio incluido en un rango específico, que está entre un mínimo y un máximo.
Leí sobre /dev/random
, /dev/urandom
y $RANDOM
, pero ninguno de estos puede hacer lo que necesito.
¿Hay otro comando útil o una forma de usar los datos anteriores?
shell
command-line
command
random
BowPark
fuente
fuente
Respuestas:
En el cofre de herramientas POSIX, puede usar
awk
:No , no usar eso como una fuente para generar contraseñas o datos secretos, por ejemplo, como ocurre con la mayoría de
awk
las implementaciones, el número fácilmente se puede adivinar en base al tiempo que comando se ha ejecutado.Con muchas
awk
implementaciones, ese comando ejecutado dos veces en el mismo segundo generalmente le dará la misma salida.fuente
x=$(awk -v min=$min_var -v max=$max_var 'BEGIN{srand(); printf("%.2d", int(min+rand()*(max-min+1)))}')
awk -v min=5 -v max=10 -v seed="$(od -An -N4 -tu4 /dev/urandom)" 'BEGIN{srand(seed+0); print int(min+rand()*(max-min+1))}'
. Podría usar en$RANDOM
lugar de,od ... /dev/random
pero su valor inicial está en el rango relativamente pequeño de 0 a 32767, por lo que probablemente obtendrá repeticiones notables en su salida con el tiempo.Puedes probar
shuf
desde GNU coreutils:fuente
shuf
.jota
En BSD y OSX puede usar jot para devolver un solo número aleatorio (
-r
) desde el intervalomin
hastamax
, inclusive.Problema de distribución
Desafortunadamente, el rango y la distribución de los números generados aleatoriamente están influenciados por el hecho de que jot usa aritmética de coma flotante de doble precisión internamente y printf (3) para el formato de salida, lo que causa problemas de redondeo y truncamiento. Por lo tanto, los intervalos
min
ymax
se generan con menos frecuencia como se demuestra:En OS X 10.11 (El Capitan) esto parece haberse solucionado:
y...
Resolviendo el problema de distribución
Para versiones anteriores de OS X, afortunadamente hay varias soluciones. Una es usar la conversión entera printf (3). La única advertencia es que el intervalo máximo ahora se convierte
max+1
. Al utilizar el formato de enteros, obtenemos una distribución justa en todo el intervalo:La solución perfecta
Finalmente, para obtener un lanzamiento justo de los dados usando la solución, tenemos:
Tarea extra
Ver jot (1) para los detalles de formato y matemática sangrientos y muchos más ejemplos.
fuente
La
$RANDOM
variable normalmente no es una buena forma de generar buenos valores aleatorios. La salida de/dev/[u]random
necesidad también debe convertirse primero.Una forma más fácil es usar lenguajes de nivel superior, como por ejemplo python:
Para generar una variable entera aleatoria entre 5 y 10 (5 <= N <= 10), use
No use esto para aplicaciones criptográficas.
fuente
Puede obtener el número aleatorio a través de
urandom
head -200 /dev/urandom | cksum
Salida:
3310670062 52870
Para recuperar la parte del número anterior.
head -200 /dev/urandom | cksum | cut -f1 -d " "
Entonces la salida es
3310670062
fuente
head -200
(o su equivalente POSIXhead -n 100
) devuelve las primeras 200 líneas de/dev/urandom
./dev/urandom
no es un archivo de texto, ese comando podría regresar de 200 bytes (todos los 0x0a, LF en ASCII) al infinito (si el byte 0xa nunca se devuelve) pero los valores entre 45k y 55k son los más probables. cksum devuelve un número de 32 bits, por lo que no tiene sentido obtener más de 4 bytes/dev/urandom
.Para generar una variable entera aleatoria entre 5 y 10 (incluidos ambos), use
%
funciona como operador de módulo.Probablemente hay mejores formas de convertir la variable aleatoria
$RANDOM
en un rango específico. No utilice esto para aplicaciones criptográficas o en casos en que necesite variables aleatorias reales, distribuidas equitativamente (como para simulaciones).fuente
# echo $(( $RANDOM % 256 ))
producirá un número "aleatorio" entre 0-255 en dialectos * sh modernos.fuente
Quizás el
UUID
(en Linux) se pueda usar para recuperar el número aleatorioPara obtener el número aleatorio entre
70
y100
fuente
Esto generará un número hexadecimal de 8 dígitos.
fuente
Para permanecer completamente dentro de bash y usar la variable $ RANDOM pero evitar la distribución desigual:
Este ejemplo proporcionaría números aleatorios del 20 al 29.
fuente
$r
debe inicializarse a 65535 u otro valor alto para evitar un[: -lt: unary operator expected
error.La distribución es buena:
for ((i = 1; i <= 100000; i ++)) do echo $ ((RANDOM% (20 - 10 + 1) + 10)); hecho | ordenar -n | uniq -c
valor de conteo
9183 10
9109 11
8915 12
9037 13
9100 14
9138 15
9125 16
9261 17
9088 18
8996 19
9048 20
fuente