일반적으로 Linux, UNIX, BSD 및 cygwin 시스템의 /dev/urandom에서 주어진 범위의 난수를 얻는 방법은 다음과 같습니다.
217 < X < 34523
또는 다른 예:
36856 < X < 76543
무작위성 관점에서 100% 정확해야 하기 때문에 단순히 '구글과 첫 번째 클릭'이 아니라 해결책을 찾으려고 노력하는 것조차 고민이 됩니다.
나는 그것을 직접 작성해 보았습니다.
$ cat randomfournumbers.sh
#!/bin/bash
working=true
howmanyneeded=0
while "$working"; do
fivedigit=$(tr -cd "[:digit:]"</dev/urandom|fold -w5|head -1)
if [ "$fivedigit" -ge 300 ]; then
if [ "$fivedigit" -le 33000 ]; then
echo "$fivedigit"
howmanyneeded=$((howmanyneeded+1))
if [ "$howmanyneeded" -ge 4 ]; then
working=false
fi
fi
fi
done
$ sh randomfournumbers.sh
11442
26742
13905
23547
$
하지만 내가 아는 한, 암호화, 무작위성... 내가 볼 수 없는 버그가 포함되어 있다고 확신합니다(urandom에는 문제가 없으며 논리입니다).
답변1
shuf
나는 이것이 더 나은 도구라고 생각합니다 .
예:
$ shuf -i 217-34523 -n 1
11623
하지만 정말로 를 사용하고 싶다면 /dev/urandom
다음과 같이 하면 됩니다.
random_numbers() {
a="$1"
b="$2"
lim="$3"
count="0"
while :; do
num=$(tr -dc '0-9\n' < /dev/urandom | grep -Pom1 "^\\d{${#a},${#b}}")
if [ "$num" -ge "$a" ] && [ "$num" -le "$b" ]; then
echo "$num"
count="$((count + 1))"
[ "$count" -ge "$lim" ] && break
fi
done
}
예:
$ random_numbers 36856 76543 5
75544
55383
43024
72678
63635
답변2
이 스크립트의 기능은 다음과 같습니다.
#!/bin/bash
log2x(){
local bytes=0 t=$1
while ((t>0)); do
((t=t>>8,bytes++))
done
echo "$bytes"
}
mkrandom(){
while :; do
hexrandom=$(dd if=/dev/urandom bs=1 count=$bytes 2>/dev/null | xxd -p)
(( 16#$hexrandom < range*mult )) && break
done
echo "$(( (16#$hexrandom%range)+min ))"
}
if (($#==3)); then
min=$2 max=$(($3+1))
else
min=217 max=34523
fi
range=$((max-min+1))
bytes=$(log2x "$range")
maxvalue=$(((1<<($bytes*8))-1))
mult=$((maxvalue/range))
#printf "maxvalue=%d mult=%d range=%d\n" "$maxvalue" "$mult" "$range"
while ((i++<$1)); do
mkrandom
done
호출 방법은 다음과 같습니다 ./script count min max
.
./script 5 23 323
261
319
189
204
93