code

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

starcafe 2023. 4. 13. 21:00
반응형

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

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

사용. 간단한 셸 산술과 조합하여 사용할 수 있습니다.예를 들어 1~10(포함)의 난수를 생성하려면 다음 절차를 수행합니다.

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

는 실실음음음 the the the the음 。variables.c의 , 「」brand()이전 버전은 단순한 선형 생성기였습니다.버전 4.0 /bash1985년 논문의 인용문이 있는 발전기를 사용해요 그게 아마 가난수라는 의미일 거예요시뮬레이션에는 사용하지 않지만(암호화에는 사용하지 않지만) 기본적인 스크립트 작업에는 적합합니다.

한 일을 할 는 '난수'를 해도 됩니다./dev/random ★★★★★★★★★★★★★★★★★」/dev/urandom다음 중 하나:

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

다음을 참조해 주세요.

$RANDOM는 0 ~ 32767 범위의 의사난수 정수를 반환하는 내부 Bash 함수(정수가 아님)입니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

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

shuf -i 1-100000 -n 1

셸에서 시험해 보세요.

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

서서,,-t d는 출력 을 10진수로 을 지정합니다.「 10 」 。-N 1요./dev/urandom.

당신은 또한 awk에서 난수를 얻을 수 있다.

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

나는 이 트릭을 좋아한다.

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

...

$RANDOM이 있습니다.그게 어떻게 작동하는지 정확히는 모르겠어요.하지만 그것은 효과가 있다.테스트의 경우 다음 작업을 수행할 수 있습니다.

echo $RANDOM

bash 5.1은 시스템의 엔트로피 엔진에서 랜덤 데이터를 가져오므로 선형적이지 않고 동일한 랜덤 시퀀스를 얻기 위해 다시 시딩할 수 없는 새로운 변수를 도입했습니다.이 변수는 다음을 대신할 수 있습니다.RANDOM많은 난수를 생성할 수 있습니다.

$ echo $((1 + SRANDOM % 10))
4

0과 9 사이의 난수입니다.

echo $((RANDOM%10))

나는 이것에 대해 몇 개의 기사를 썼다.

$ RANDOM=$(date +%s%N | cut -b10-19)
$ echo $(( $RANDOM % 113 + 13 ))

상기의 값은 13~125(113-1+13)의 수치로, 적당한 랜덤 엔트로피를 가집니다.

Linux 시스템을 사용하는 경우 /dev/random 또는 /dev/urandom에서 랜덤 번호를 얻을 수 있습니다.사용 가능한 난수가 충분하지 않으면 be carefull /dev/random이 차단됩니다.랜덤성에 대한 속도가 필요한 경우 /dev/urandom을 사용합니다.

이러한 「파일」은, operating system에 의해서 생성된 랜덤 번호로 채워집니다.true 또는 의사 난수를 얻을 경우 시스템에 /dev/random을 구현하는 방법에 따라 달라집니다.마우스, 하드 드라이브, 네트워크 등의 디바이스 드라이버에서 수집된 도움말 폼 노이즈로 진정한 난수가 생성됩니다.

dd 파일로부터 랜덤 번호를 취득할 수 있습니다.

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

이러한 디바이스는 읽었을 때 정말로 랜덤한 번호를 반환하며, 애플리케이션 소프트웨어가 암호화를 위해 안전한 키를 선택할 수 있도록 설계되었습니다.이러한 난수는 다양한 랜덤 이벤트에 의해 기여되는 엔트로피 풀에서 추출됩니다.{LDD3, Jonathan Corbet, Alessandro Rubini 및 Greg Kroah-Hartman}

이들 2개의 파일은 특히 커널 랜덤화에 대한 인터페이스입니다.

void get_random_bytes_arch(void* buf, int nbytes)

이러한 기능이 하드웨어에 의해 실장되어 있는 경우(통상은 실장되어 있는 경우), 또는 엔트로피 풀(마우스와 키보드 인터럽트, SA_SAMPLE_RANDOM에 등록되어 있는 기타 인터럽트 사이의 타이밍을 합한 값)에서 가져옵니다.

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

만, 은, 것만만만만만만만만만만만만 from from from from from from from from from from from from에서 씁니다.dd. 줍니다.다음 명령어는 필요한 정수만 제공합니다.산술적 확장에 주어진 비트마스크를 조정하여 필요에 따라 지정된 수의 랜덤 비트를 얻을 수도 있습니다.

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

몇 가지 아이디어를 취해서 난수가 많으면 빨리 실행할 수 있는 기능을 만들었습니다.

, " "od많은 난수가 필요한 경우 비용이 많이 듭니다./dev/urandom 1024입니다.rand호출되어 마지막 난수가 반환되고 크기가 조정됩니다.그런 다음 캐시에서 삭제됩니다.캐시가 비어 있으면 1024개의 랜덤 번호가 읽힙니다.

예:

rand 10; echo $RET

0 ~ 9 사이의 RET 난수를 반환합니다.

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 <= 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

늦었을지도 , ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★jotBash의 범위 내에서 랜덤한 숫자를 생성할 수 있습니까?

jot -r -p 3 1 0 1

에 의해 랜덤)이 됩니다.-r 이하 3」)-p 사이의 (예: 0에서 1까지)를 수 1 0 1 ).설명서에 따르면 난수의 출처는 다음과 같습니다.

시드가 지정되지 않은 경우에는 arc4random(3)을 통해, 시드가 지정된 경우에는 랜덤(3)을 통해 난수를 구한다.

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

그럼 어떻게 되는 거죠?

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

모듈링을 사용하지 않는 순수 Bash 난수

lowerRange=10   # inclusive
upperRange=20   # exclusive

randomNumber=$(( RANDOM * ( upperRange - lowerRange) / 32767 + lowerRange ))

시드를 사용할 수 있습니다. 다음 문서를 참조하십시오.

RANDOM=$(date +%s%N | cut -b10-19)
echo $(( $RANDOM % 100 + 1 ))

@Nelson, @Barun 및 @Robert의 훌륭한 답변을 바탕으로 난수를 생성하는 Bash 스크립트를 다음에 나타냅니다.

  • 원하는 자리수를 생성할 수 있습니다.
  • 됩니다./dev/urandom배쉬의 빌트인보다 훨씬 낫습니다.$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

프로그램의 랜덤 분기 또는 yes/no; 1/0, true/false 출력:

if [ $RANDOM -gt 16383  ]; then              # 16383 = 32767/2 
    echo var=true/1/yes/go_hither
else 
    echo var=false/0/no/go_thither
fi

16383을 기억하는 것이 귀찮다면:

if (( RANDOM % 2 )); then 
    echo "yes"
else 
    echo "no"
fi

dd 및 od를 사용하지 않고 /dev/urandom을 사용하려고 했습니다.

function roll() { local modulus=${1:-6}; echo $(( 1 + 0x$(env LC_CTYPE=C tr -dc '0-9a-fA-F' < /dev/urandom | head -c5 ) % $modulus )); }

테스트

$ roll
5
$ roll 12
12

얼마나 무작위적인가요?

$ (echo "count roll percentage"; i=0; while [ $i -lt 10000 ]; do roll; i=$((i+1)); done | sort | uniq -c | awk '{print $0,($1/10000*100)"%"}') | column -t
count  roll  percentage
1625   1     16.25%
1665   2     16.65%
1646   3     16.46%
1720   4     17.2%
1694   5     16.94%
1650   6     16.5%

난수 3자리 숫자 생성

이것은 샘플 데이터를 만드는 데 유용합니다.예: 모든 테스트 데이터를 "test-create-volume-123"이라는 디렉토리에 넣은 후 테스트가 완료되면 디렉토리 전체를 잽합니다.정확히 세 자리만 생성하면 이상한 정렬 문제가 발생하지 않습니다.

printf '%02d\n' $((1 + RANDOM % 100))

예를 들어 다음과 같이 한 자리까지 축소됩니다.

printf '%01d\n' $((1 + RANDOM % 10))

네 자리까지 확장됩니다.그 이유에 대해서는, 상기를 참조해 주세요:)

perl을 사용하여 n자리 수의 랜덤을 생성하는 bash 함수.자리수 또는 n 0 의 템플릿을 지정합니다.

rand() {
  perl -E '$ARGV[0]||=""; $ARGV[0]=int($ARGV[0])||length($ARGV[0]); say join "", int(rand(9)+1)*($ARGV[0]?1:0), map { int(rand(10)) } (0..($ARGV[0]||0)-2)' $1
}

사용방법:

$ rand 3
381
$ rand 000
728

0 ~ 15 의 n 에 대해서, 발신측 랜드 n 의 데먼스트레이션:

$ for n in {0..15}; do printf "%02d: %s\n" $n $(rand $n); done
00: 0
01: 3
02: 98
03: 139
04: 1712
05: 49296
06: 426697
07: 2431421
08: 82727795
09: 445682186
10: 6368501779
11: 51029574113
12: 602518591108
13: 5839716875073
14: 87572173490132
15: 546889624135868

호출 랜드n의 시연(n의 경우 길이0 ~ 15 의 0 의 템플릿)

$ for n in {0..15}; do printf "%15s :%02d: %s\n" $(printf "%0${n}d" 0) $n $(rand $(printf "%0${n}d" 0)); done
              0 :00: 0
              0 :01: 0
             00 :02: 70
            000 :03: 201
           0000 :04: 9751
          00000 :05: 62237
         000000 :06: 262860
        0000000 :07: 1365194
       00000000 :08: 83953419
      000000000 :09: 838521776
     0000000000 :10: 2355011586
    00000000000 :11: 95040136057
   000000000000 :12: 511889225898
  0000000000000 :13: 7441263049018
 00000000000000 :14: 11895209107156
000000000000000 :15: 863219624761093

원하는 범위의 난수를 출력하는 함수를 작성했습니다>

설명:

random <min> <max>

"에서 min로로 합니다.max , . 둘 .min ★★★★★★★★★★★★★★★★★」max수일 수 단, 범위 내에서는 음수일 수 있습니다.(max - min + 1)~ 32767. =을 사용하다

그 핵심은 다음과 같습니다.

random() {
    min="$1"
    max="$2"
    
    range=$((max - min + 1))
    rand=$((min + (RANDOM % range)))
    echo "$rand"
}

사용방법:

# general form: obtain a random number between min and max, inclusive
random <min> <max>

# Example: obtain a random number from -10 to 10, inclusive
random -10 10

은 bash 합니다.RANDOM마 C 、 C 만 C 만 , , , , , , , , , , , , , , , ,rand()개 이므로 32767을 참조하십시오

  1. https://en.cppreference.com/w/c/numeric/random/rand
  2. https://en.cppreference.com/w/c/numeric/random/RAND_MAX

의 메뉴얼에 는, bash 의 「」, 「」를 .man bash:

RANDOM

마다 이 each の 음음 の between between の between の between between between between between between between의 임의의 0 ★★★★★★★★★★★★★★★★★」32767 the numbers may of the the the the the the the the the the the the the the the the a a a a a a a a a a a a에 값을 할당하여 난수의 순서를 할 수 있습니다.RANDOM.RANDOMunset그 후에 리셋 되어도, 그 특수한 속성이 없어집니다.

가능, " " " " " ,source의 유효

더 의 나의 것이 .random위의 기능을 수행합니다. 체크,, 도움말 메뉴, 에러 체크, 범위 체크 등이 .random --help ★★★★★★★★★★★★★★★★★」random -h및 「 」run_check 를 소스 실행할 수 .source the it it를 합니다.randomPython에서 할 수 있는 것처럼 다른 스크립트로 기능합니다.

random.sh <--이 링크를 클릭하면 항상 eRCaGuy_dotfiles repo에서 최신 버전을 얻을 수 있습니다.

RETURN_CODE_SUCCESS=0
RETURN_CODE_ERROR=1

HELP_STR="\
Generate a random integer number according to the usage styles below.

USAGE STYLES:
    'random'
        Generate a random number from 0 to 32767, inclusive (same as bash variable 'RANDOM').
    'random <max>'
        Generate a random number from 0 to 'max', inclusive.
    'random <min> <max>'
        Generate a random number from 'min' to 'max', inclusive. Both 'min' and 'max' can be
        positive OR negative numbers, and the generated random number can be negative too, so
        long as the range (max - min + 1) is less than or equal to 32767. Max must be >= min.

This file is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
"

print_help() {
    echo "$HELP_STR" | less -RFX
}

# Get a random number according to the usage styles above.
# See also `utils_rand()` in utilities.c:
# https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/utilities.c#L176
random() {
    # PARSE ARGUMENTS

    # help menu
    if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
        print_help
        exit $RETURN_CODE_SUCCESS
    fi

    # 'random'
    if [ $# -eq 0 ]; then
        min=0
        max="none"
    # 'random max'
    elif [ $# -eq 1 ]; then
        min=0
        max="$1"
    # 'random min max'
    elif [ $# -eq 2 ]; then
        min="$1"
        max="$2"
    else
        echo "ERROR: too many arguments."
        exit "$RETURN_CODE_ERROR"
    fi

    # CHECK FOR ERRORS

    if [ "$max" = "none" ]; then
        rand="$RANDOM"
        echo "$rand"
        exit "$RETURN_CODE_SUCCESS"
    fi

    if [ "$max" -lt "$min" ]; then
        echo "ERROR: max ($max) < min ($min). Max must be >= min."
        exit "$RETURN_CODE_ERROR"
    fi

    # CALCULATE THE RANDOM NUMBER

    # See `man bash` and search for `RANDOM`. This is a limitation of that value.
    RAND_MAX=32767

    range=$((max - min + 1))
    if [ "$range" -gt "$RAND_MAX" ]; then
        echo "ERROR: the range (max - min + 1) is too large. Max allowed = $RAND_MAX, but actual" \
             "range = ($max - $min + 1) = $range."
        exit "$RETURN_CODE_ERROR"
    fi

    # NB: `RANDOM` is a bash built-in variable. See `man bash`, and also here:
    # https://stackoverflow.com/a/1195035/4561887
    rand=$((min + (RANDOM % range)))
    echo "$rand"
}

# Set the global variable `run` to "true" if the script is being **executed** (not sourced) and
# `main` should run, and set `run` to "false" otherwise. One might source this script but intend
# NOT to run it if they wanted to import functions from the script.
# See:
# 1. *****https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/bash/argument_parsing__3_advanced__gen_prog_template.sh
# 1. my answer: https://stackoverflow.com/a/70662049/4561887
# 1. https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/bash/check_if_sourced_or_executed.sh
run_check() {
    # This is akin to `if __name__ == "__main__":` in Python.
    if [ "${FUNCNAME[-1]}" == "main" ]; then
        # This script is being EXECUTED, not sourced
        run="true"
    fi
}

# ----------------------------------------------------------------------------------------------------------------------
# Main program entry point
# ----------------------------------------------------------------------------------------------------------------------

# Only run main function if this file is being executed, NOT sourced.
run="false"
run_check
if [ "$run" == "true" ]; then
    random "$@"
fi

다른 종속성은 필요하지 않습니다.

$(((RANDOM % $((upperBound - lowerBound))) + lowerBound))

는 「」입니다.[lowerBound,upperBound)

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

반응형