Вопрос:
Как создать случайное число в диапазоне в 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 %dn» $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. Приведенная ниже команда дает только целое число, которое мне нужно. Я даже могу получить определенное количество случайных бит, сколько мне нужно, отрегулировав битмаску, заданную для арифметического расширения:
me@mymachine:~/$ 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