Permitir apenas um determinado intervalo de números de / dev / urandom

2

Em geral, em sistemas Linux, UNIX, BSD, cygwin, como posso obter números aleatórios de / dev / urandom dentro de um determinado intervalo, por exemplo:

217 < X < 34523

OU outro exemplo:

36856 < X < 76543 

Eu tenho medo de tentar procurar por soluções, já que isso não é apenas "google e first hit", porque tem que ser 100% correto do ponto de vista da aleatoriedade.

Eu tentei escrever por mim mesmo:

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

Mas afaik criptografia, aleatoriedade .. Eu tenho certeza que contém um erro que não consigo ver (nenhum problema com o urandom, e sim a lógica).

    
por whoonetets 30.12.2017 / 22:05

2 respostas

1

Acho que shuf seria uma ferramenta melhor para esse fim.

Exemplo:

$ shuf -i 217-34523 -n 1
11623

Mas se você realmente quiser usar /dev/urandom , isso deve funcionar:

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
}

Exemplo:

$ random_numbers 36856 76543 5
75544
55383
43024
72678
63635
    
por 30.12.2017 / 22:19
0

Este script faz o trabalho:

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

Ligue como ./script count min max :

./script 5 23 323
261
319
189
204
93
    
por 31.12.2017 / 00:36

Tags