Как создать случайное число в диапазоне в Bash?
Как создать случайное число в Bash?
Ответ 1
Используйте $RANDOM
. Это часто полезно в сочетании с простой арифметикой оболочки. Например, для генерации случайного числа между 1 и 10:
$ echo $((1 + RANDOM % 10))
3
Фактический генератор находится в variables.c
, функции brand()
. Старые версии были простым линейным генератором. Версия 4.0 из bash
использует генератор
Ответ 2
См. $RANDOM
:
$RANDOM
- внутренняя функция Bash(не константа), которая возвращает Псевдослучайное целое число в диапазоне 0 - 32767. Его нельзя использовать для сгенерировать ключ шифрования.
Ответ 3
Попробуйте это из своей оболочки:
$ od -A n -t d -N 1 /dev/urandom
Здесь -t d
указывает, что формат вывода должен быть подписан десятичным; -N 1
говорит читать один байт от /dev/urandom
.
Ответ 4
Вы также можете использовать shuf (доступно в coreutils).
shuf -i 1-100000 -n 1
Ответ 5
вы также можете получить случайное число из awk
awk 'BEGIN {
# seed
srand()
for (i=1;i<=1000;i++){
print int(1 + rand() * 100)
}
}'
Ответ 6
Существует $RANDOM. Я точно не знаю, как это работает. Но это работает. Для тестирования вы можете:
echo $RANDOM
Ответ 7
Случайное число от 0 до 9 включительно.
echo $((RANDOM%10))
Ответ 8
Мне нравится этот трюк:
echo ${RANDOM:0:1} # random number between 1 and 9
echo ${RANDOM:0:2} # random number between 1 and 99
...
Ответ 9
Если вы используете систему linux, вы можете получить случайное число из /dev/random или/dev/urandom. Будьте осторожны /dev/random будет блокироваться, если не будет достаточно случайных чисел. Если вам нужна скорость над случайностью, используйте /dev/urandom.
Эти "файлы" будут заполнены случайными числами, сгенерированными операционной системой. Это зависит от реализации /dev/random в вашей системе, если вы получаете истинные или псевдослучайные числа. Истинные случайные числа генерируются с помощью формы сигнала, собранной из драйверов устройств, таких как мышь, жесткий диск, сеть.
Вы можете получить случайные числа из файла с помощью dd
Ответ 10
Я взял несколько из этих идей и сделал функцию, которая должна выполняться быстро, если требуется множество случайных чисел.
вызов od
стоит дорого, если вам нужно много случайных чисел. Вместо этого я вызываю его один раз и сохраняю 1024 случайных числа из /dev/urandom. Когда вызывается rand
, последнее случайное число возвращается и масштабируется. Затем он удаляется из кеша. Когда кеш пуст, считываются еще 1024 случайных числа.
Пример:
rand 10; echo $RET
Возвращает случайное число в RET между 0 и 9 включительно.
declare -ia RANDCACHE
declare -i RET RAWRAND=$(( (1<<32)-1 ))
function rand(){ # pick a random number from 0 to N-1. Max N is 2^32
local -i N=$1
[[ ${#RANDCACHE[*]} -eq 0 ]] && { RANDCACHE=( $(od -An -tu4 -N1024 /dev/urandom) ); } # refill cache
RET=$(( (RANDCACHE[-1]*N+1)/RAWRAND )) # pull last random number and scale
unset RANDCACHE[${#RANDCACHE[*]}-1] # pop read random number
};
# test by generating a lot of random numbers, then effectively place them in bins and count how many are in each bin.
declare -i c; declare -ia BIN
for (( c=0; c<100000; c++ )); do
rand 10
BIN[RET]+=1 # add to bin to check distribution
done
for (( c=0; c<10; c++ )); do
printf "%d %d\n" $c ${BIN[c]}
done
UPDATE: это не так хорошо для всех N. Он также отбрасывает случайные биты, если используется с малым N. Отмечая, что (в этом случае) 32-битное случайное число имеет достаточно энтропии для 9 случайных чисел от 0 до 9 ( 10 * 9 = 1,000,000,000 <= 2 * 32), мы можем извлекать несколько случайных чисел из каждого 32 случайного значения источника.
#!/bin/bash
declare -ia RCACHE
declare -i RET # return value
declare -i ENT=2 # keep track of unused entropy as 2^(entropy)
declare -i RND=RANDOM%ENT # a store for unused entropy - start with 1 bit
declare -i BYTES=4 # size of unsigned random bytes returned by od
declare -i BITS=8*BYTES # size of random data returned by od in bits
declare -i CACHE=16 # number of random numbers to cache
declare -i MAX=2**BITS # quantum of entropy per cached random number
declare -i c
function rand(){ # pick a random number from 0 to 2^BITS-1
[[ ${#RCACHE[*]} -eq 0 ]] && { RCACHE=( $(od -An -tu$BYTES -N$CACHE /dev/urandom) ); } # refill cache - could use /dev/random if CACHE is small
RET=${RCACHE[-1]} # pull last random number and scale
unset RCACHE[${#RCACHE[*]}-1] # pop read random number
};
function randBetween(){
local -i N=$1
[[ ENT -lt N ]] && { # not enough entropy to supply ln(N)/ln(2) bits
rand; RND=RET # get more random bits
ENT=MAX # reset entropy
}
RET=RND%N # random number to return
RND=RND/N # remaining randomness
ENT=ENT/N # remaining entropy
};
declare -ia BIN
for (( c=0; c<100000; c++ )); do
randBetween 10
BIN[RET]+=1
done
for c in ${BIN[*]}; do
echo $c
done
Ответ 11
Чтение из /dev/random или/dev/urandom символов специальных файлов - это путь.
Эти устройства возвращают по-настоящему случайные числа при чтении и чтобы помочь прикладному программному обеспечению выбрать безопасные ключи для шифрования. такие случайные числа извлекаются из пула энтропии, который различными случайными событиями. {LDD3, Джонатан Корбет, Алессандро Рубини и Грег Кроа-Хартман]
Эти два файла являются интерфейсом для рандомизации ядра, в частности
void get_random_bytes_arch(void* buf, int nbytes)
который извлекает поистине случайные байты из аппаратного обеспечения, если такая функция осуществляется с помощью аппаратного обеспечения (как правило, это), или она извлекается из пула энтропии (состоящего из таймингов между событиями, такими как прерывания мыши и клавиатуры и другие прерывания, зарегистрированные в SA_SAMPLE_RANDOM).
dd if=/dev/urandom count=4 bs=1 | od -t d
Это работает, но записывает ненужный вывод из dd
в stdout. Приведенная ниже команда дает только целое число, которое мне нужно. Я даже могу получить определенное количество случайных бит, сколько мне нужно, отрегулировав битмаску, заданную для арифметического расширения:
[email protected]:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump
-d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))
Ответ 12
Генерировать случайное число в диапазоне от 0 до n (16-битное целое число). Результат устанавливается в переменной $RAND. Например:
#!/bin/bash
random()
{
local range=${1:-1}
RAND=`od -t uI -N 4 /dev/urandom | awk '{print $2}'`
let "RAND=$RAND%($range+1)"
}
n=10
while [ $(( n -=1 )) -ge "0" ]; do
random 500
echo "$RAND"
done
Ответ 13
Как насчет:
perl -e 'print int rand 10, "\n"; '
Ответ 14
Может быть, я немного опоздал, но как насчет использования jot
для генерации случайного числа в диапазоне в Bash?
jot -r -p 3 1 0 1
Это генерирует случайное (-r
) число с точностью до 3 десятичных знаков (-p
). В этом конкретном случае вы получите одно число от 0 до 1 (1 0 1
). Вы также можете распечатать последовательные данные. Источник случайного числа, согласно руководству, является:
Случайные числа получаются с помощью arc4random (3), когда начальное число не указано, и с помощью случайный (3), когда дается семя.
Ответ 15
Основанный на замечательных ответах @Nelson, @Barun и @Robert, вот скрипт Bash, который генерирует случайные числа.
- Может генерировать, сколько цифр вы хотите.
- каждая цифра генерируется отдельно
/dev/urandom
, что намного лучше, чем встроенная в Bash$RANDOM
#!/usr/bin/env bash
digits=10
rand=$(od -A n -t d -N 2 /dev/urandom |tr -d ' ')
num=$((rand % 10))
while [ ${#num} -lt $digits ]; do
rand=$(od -A n -t d -N 1 /dev/urandom |tr -d ' ')
num="${num}$((rand % 10))"
done
echo $num