Как создать случайное число в 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