IT story

Bash에서 난수를 생성하는 방법은 무엇입니까?

hot-time 2020. 5. 17. 10:42
반응형

Bash에서 난수를 생성하는 방법은 무엇입니까?


Bash에서 범위 내에서 난수를 생성하는 방법은 무엇입니까?


사용하십시오 $RANDOM. 간단한 쉘 산술과 결합하여 종종 유용합니다. 예를 들어 1에서 10 사이의 난수를 생성하려면

$ echo $((1 + RANDOM % 10))
3

실제 발생기는 variables.c함수에 brand()있습니다. 이전 버전 은 간단한 선형 생성기였습니다. 버전 4.0은 1985 년 논문을 인용bash발전기사용하는데 , 이는 아마도 의사 난수의 적절한 출처임을 의미합니다. 시뮬레이션에 사용하지는 않지만 (암호화에는 사용하지는 않지만) 기본 스크립팅 작업에는 적합합니다.

심각한 임의의 숫자가 필요한 작업을 수행 중이 /dev/random거나 사용 /dev/urandom가능한 경우 :

$ dd if=/dev/urandom count=4 bs=1 | od -t d

참조하십시오 $RANDOM:

$RANDOM 0-32767 범위의 의사 난수 정수를 반환하는 내부 Bash 함수 (상수 아님)입니다. 암호화 키를 생성하는 데 사용해서는 안됩니다.


쉘에서 이것을 시도하십시오 :

$ od -A n -t d -N 1 /dev/urandom

여기 -t d에서 출력 형식이 10 진수 부호로 지정되도록 지정합니다. -N 1에서 1 바이트를 읽도록 지시 /dev/urandom합니다.


shuf (coreutils에서 사용 가능)를 사용할 수도 있습니다 .

shuf -i 1-100000 -n 1

당신은 또한 awk에서 임의의 숫자를 얻을 수 있습니다

awk 'BEGIN {
   # seed
   srand()
   for (i=1;i<=1000;i++){
     print int(1 + rand() * 100)
   }
}'

$ RANDOM이 있습니다. 나는 그것이 어떻게 작동하는지 정확히 모른다. 그러나 작동합니다. 테스트를 위해 다음을 수행 할 수 있습니다.

echo $RANDOM

0에서 9 사이의 난수.

echo $((RANDOM%10))

나는이 트릭을 좋아한다 :

echo ${RANDOM:0:1} # random number between 1 and 9
echo ${RANDOM:0:2} # random number between 1 and 99

...


리눅스 시스템을 사용하는 경우 / dev / random 또는 / dev / urandom 에서 임의의 숫자를 얻을 수 있습니다 . 사용할 수있는 난수가 충분하지 않으면 / dev / random이 차단됩니다. 임의성에 대한 속도가 필요한 경우 / dev / urandom을 사용하십시오.

이 "파일"은 운영 체제에서 생성 된 난수로 채워집니다. 참 또는 의사 난수를 얻는 경우 시스템에서 / dev / random의 구현에 따라 다릅니다. 마우스, 하드 드라이브, 네트워크와 같은 장치 드라이버에서 수집 된 노이즈를 통해 정확한 임의의 숫자가 생성됩니다.

dd 를 사용하여 파일에서 임의의 숫자를 얻을 수 있습니다


나는 이러한 아이디어 중 몇 가지를 취했으며 많은 난수가 필요한 경우 신속하게 수행 해야하는 기능을 만들었습니다.

od많은 난수가 필요한 경우 통화 비용이 많이 듭니다. 대신 한 번 호출하여 / dev / urandom에서 1024 개의 난수를 저장합니다. 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

업데이트 : 그것은 모든 N에 대해 잘 작동하지 않습니다. 작은 N과 함께 사용하면 임의의 비트가 낭비됩니다.이 경우 32 비트 임의의 숫자는 0과 9 사이의 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

/ dev / random 또는 / dev / urandom 문자 특수 파일에서 읽는 것이 좋습니다.

These devices return truly random numbers when read and are designed to help application software choose secure keys for encryption. Such random numbers are extracted from an entropy pool that is contributed by various random events. {LDD3, Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman]

These two files are interface to kernel randomization, in particular

void get_random_bytes_arch(void* buf, int nbytes)

which draws truly random bytes from hardware if such function is by hardware implemented (usually is), or it draws from entropy pool (comprised of timings between events like mouse and keyboard interrupts and other interrupts that are registered with SA_SAMPLE_RANDOM).

dd if=/dev/urandom count=4 bs=1 | od -t d

This works, but writes unneeded output from dd to stdout. The command below gives just the integer I need. I can even get specified number of random bits as I need by adjustment of the bitmask given to arithmetic expansion:

me@mymachine:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump 
                         -d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))

Generate random number in the range of 0 to n (signed 16-bit integer). Result set in $RAND variable. For example:

#!/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

What about:

perl -e 'print int rand 10, "\n"; '

Maybe I am a bit too late, but what about using jot to generate a random number within a range in Bash?

jot -r -p 3 1 0 1

This generates a random (-r) number with 3 decimal places precision (-p). In this particular case, you'll get one number between 0 and 1 (1 0 1). You can also print sequential data. The source of the random number, according to the manual, is:

Random numbers are obtained through arc4random(3) when no seed is specified, and through random(3) when a seed is given.


Based on the great answers of @Nelson, @Barun and @Robert, here is a Bash script that generates random numbers.

  • Can generate how many digits you want.
  • each digit is separately generated by /dev/urandom which is much better than Bash's built-in $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

참고URL : https://stackoverflow.com/questions/1194882/how-to-generate-random-number-in-bash

반응형