인터넷 검색을 한 후 쉘 명령을 사용하여 특정 범위에 포함 된 임의의 십진 정수를 생성하는 간단한 방법을 찾을 수 없었습니다. 최소와 최대 사이입니다.
나는 읽어 /dev/random
, /dev/urandom
그리고 $RANDOM
,이 중에 내가 필요로 무엇을 할 수 없다.
다른 유용한 명령이나 이전 데이터를 사용하는 방법이 있습니까?
인터넷 검색을 한 후 쉘 명령을 사용하여 특정 범위에 포함 된 임의의 십진 정수를 생성하는 간단한 방법을 찾을 수 없었습니다. 최소와 최대 사이입니다.
나는 읽어 /dev/random
, /dev/urandom
그리고 $RANDOM
,이 중에 내가 필요로 무엇을 할 수 없다.
다른 유용한 명령이나 이전 데이터를 사용하는 방법이 있습니까?
답변:
POSIX toolchest에서 다음을 사용할 수 있습니다 awk
.
awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'
마십시오 하지 대부분과 마찬가지로, 암호 또는 예를 들어 비밀 데이터를 생성하기 위해 소스로 저를 사용하여 awk
구현, 숫자를 쉽게 실행 된 명령 시간을 기준으로 추측 할 수있다.
많은 awk
구현에서, 해당 명령은 동일한 초 내에 두 번 실행되어 일반적으로 동일한 출력을 제공합니다.
x=$(awk -v min=$min_var -v max=$max_var 'BEGIN{srand(); printf("%.2d", int(min+rand()*(max-min+1)))}')
awk -v min=5 -v max=10 -v seed="$(od -An -N4 -tu4 /dev/urandom)" 'BEGIN{srand(seed+0); print int(min+rand()*(max-min+1))}'
. $RANDOM
대신에 사용할 수 od ... /dev/random
있지만 시드 값의 범위는 0에서 32767 사이로 비교적 작으므로 시간이 지남에 따라 출력에서 눈에 띄게 반복 될 수 있습니다.
BSD와 OSX에서 당신은 사용할 수 조금도 하나의 임의 (돌아 -r
간격에서) 수 min
에 max
포함.
$ min=5
$ max=10
$ jot -r 1 $min $max
불행하게도, 무작위로 생성 된 숫자의 범위와 분포는 jot이 내부에서 배정도 부동 소수점 산술을 사용하고 출력 형식에 printf (3)를 사용하여 반올림 및 잘림 문제를 유발한다는 사실에 영향을받습니다. 따라서 다음과 같이 간격 min
과 간격 max
이 덜 생성됩니다.
$ jot -r 100000 5 10 | sort -n | uniq -c
9918 5
20176 6
20006 7
20083 8
19879 9
9938 10
OS X 10.11 (El Capitan)에서는 다음과 같이 수정되었습니다.
$ jot -r 100000 5 10 | sort -n | uniq -c
16692 5
16550 6
16856 7
16579 8
16714 9
16609 10
과...
$ jot -r 1000000 1 10 | sort -n | uniq -c
100430 1
99965 2
99982 3
99796 4
100444 5
99853 6
99835 7
100397 8
99588 9
99710 10
이전 버전의 OS X의 경우 다행스럽게도 몇 가지 해결 방법이 있습니다. 하나는 printf (3) 정수 변환을 사용하는 것입니다. 유일한 경고는 이제 최대 간격이됩니다 max+1
. 정수 형식을 사용하면 전체 간격에 걸쳐 공정한 분포를 얻습니다.
$ jot -w %i -r 100000 5 11 | sort -n | uniq -c
16756 5
16571 6
16744 7
16605 8
16683 9
16641 10
마지막으로, 해결 방법을 사용하여 주사위를 공정하게 굴리려면 다음과 같은 이점이 있습니다.
$ min=5
$ max_plus1=11 # 10 + 1
$ jot -w %i -r 1 $min $max_plus1
까다로운 수학 및 서식 세부 정보 및 더 많은 예제는 jot (1) 을 참조하십시오 .
$RANDOM
변수는 일반적으로 생성 좋은 임의의 값에 좋은 방법이 아니다. 출력 /dev/[u]random
도 먼저 변환해야합니다.
더 쉬운 방법은 파이썬과 같은 고급 언어를 사용하는 것입니다.
5와 10 사이의 임의의 정수 변수를 생성하려면 (5 <= N <= 10)
python -c "import random; print random.randint(5,10)"
암호화 응용 프로그램에는 이것을 사용하지 마십시오.
당신은 난수를 통해 얻을 수 있습니다 urandom
head -200 /dev/urandom | cksum
산출:
3310670062 52870
위 숫자의 한 부분을 검색합니다.
head -200 /dev/urandom | cksum | cut -f1 -d " "
그런 다음 출력은
3310670062
head -200
(또는 해당 POSIX 해당 head -n 100
)는의 첫 200 줄 을 반환합니다 /dev/urandom
. /dev/urandom
텍스트 파일이 아닌 경우 해당 명령은 200 바이트 (모든 0x0a 1, ASCII의 LF)에서 무한대로 (0xa 바이트가 반환되지 않는 경우) 반환 할 수 있지만 45k와 55k 사이의 값이 가장 가능성이 높습니다. cksum은 32 비트 숫자를 반환하므로에서 4 바이트 이상을 가져 오는 것은 의미가 없습니다 /dev/urandom
.
5와 10 사이의 임의의 정수 변수를 생성하려면 (둘 다 포함)
echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))
%
모듈로 연산자로 작동합니다.
랜덤 변수 $RANDOM
를 특정 범위 로 변환하는 더 좋은 방법이있을 것입니다 . 암호화 응용 프로그램이나 시뮬레이션에 사용되는 등분 산 된 실제 랜덤 변수가 필요한 경우에는 이것을 사용하지 마십시오.
bash 내에 완전히 머무르고 $ RANDOM 변수를 사용하지만 고르지 않은 분포는 피하십시오.
#!/bin/bash
range=10
floor=20
if [ $range -gt 32768 ]; then
echo 'range outside of what $RANDOM can provide.' >&2
exit 1 # exit before entering infinite loop
fi
max_RANDOM=$(( 2**15/$range*$range ))
r=$RANDOM
until [ $r -lt $max_RANDOM ]; do
r=$RANDOM
done
echo $(( r % $range + $floor ))
이 예는 20에서 29 사이의 난수를 제공합니다.
$r
[: -lt: unary operator expected
오류 를 피하려면 65535 또는 기타 높은 값으로 초기화해야합니다 .