Po trochę googlowaniu nie mogłem znaleźć prostego sposobu na użycie polecenia powłoki do wygenerowania losowej liczby całkowitej dziesiętnej zawartej w określonym zakresie, tj. Między minimum a maksimum.
Czytałem o /dev/random
, /dev/urandom
a $RANDOM
, ale żaden z nich nie może zrobić to, czego potrzebuję.
Czy istnieje inne przydatne polecenie lub sposób na wykorzystanie poprzednich danych?
shell
command-line
command
random
BowPark
źródło
źródło
Odpowiedzi:
W zestawie narzędzi POSIX możesz użyć
awk
:Czy nie używać tego jako źródło do generowania haseł lub tajne dane na przykład, jak w większości
awk
implementacji, numer może się łatwo domyślić na podstawie czasu, że rozkaz został uruchomiony.W przypadku wielu
awk
implementacji to polecenie uruchomione dwukrotnie w tej samej sekundzie generalnie daje takie same wyniki.źródło
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))}'
. Możesz użyć$RANDOM
zamiast,od ... /dev/random
ale wtedy twoja wartość początkowa jest w stosunkowo małym zakresie od 0 do 32767, więc prawdopodobnie dostaniesz zauważalne powtórzenia w swoim wyniku z czasem.Możesz wypróbować
shuf
z GNU coreutils:źródło
shuf
.krztyna
W BSD i OSX możesz użyć jot, aby zwrócić pojedynczą
-r
liczbę losową ( ) z przedziałumin
domax
włącznie.Problem z dystrybucją
Niestety na zasięg i rozkład liczb generowanych losowo ma wpływ fakt, że jot używa arytmetyki zmiennoprzecinkowej podwójnej precyzji wewnętrznie i printf (3) do formatu wyjściowego, co powoduje problemy z zaokrąglaniem i obcinaniem. Dlatego interwały
min
imax
są generowane rzadziej, jak pokazano:W OS X 10.11 (El Capitan) wydaje się, że zostało to naprawione:
i...
Rozwiązanie problemu dystrybucji
Na starsze wersje OS X na szczęście istnieje kilka obejść. Jednym z nich jest użycie konwersji liczb całkowitych printf (3). Jedynym zastrzeżeniem jest to, że teraz staje się maksimum interwału
max+1
. Korzystając z formatowania liczb całkowitych, uzyskujemy sprawiedliwy rozkład w całym przedziale czasowym:Idealne rozwiązanie
Wreszcie, aby uzyskać rzetelny rzut kostkami za pomocą obejścia, mamy:
Dodatkowa praca domowa
Zobacz jot (1), aby poznać szczegóły matematyki i formatowania oraz wiele innych przykładów.
źródło
$RANDOM
Zmienna zazwyczaj nie jest dobrym sposobem na dobre wartości generowanych losowo. W/dev/[u]random
pierwszej kolejności należy również przekonwertować wynik zapotrzebowania.Łatwiejszym sposobem jest użycie języków wyższego poziomu, takich jak np. Python:
Aby wygenerować losową zmienną całkowitą z przedziału od 5 do 10 (5 <= N <= 10), użyj
Nie używaj tego do aplikacji kryptograficznych.
źródło
Możesz uzyskać losową liczbę poprzez
urandom
head -200 /dev/urandom | cksum
Wynik:
3310670062 52870
Aby pobrać jedną część powyższego numeru.
head -200 /dev/urandom | cksum | cut -f1 -d " "
Następnie wyjście jest
3310670062
źródło
head -200
(lub jego odpowiednik POSIXhead -n 100
) zwraca pierwszych 200 linii z/dev/urandom
./dev/urandom
nie jest plikiem tekstowym, to polecenie może wrócić z 200 bajtów (wszystkie 0x0a, LF w ASCII) do nieskończoności (jeśli bajt 0xa nigdy nie zostanie zwrócony), ale najbardziej prawdopodobne są wartości od 45k do 55k. cksum zwraca liczbę 32-bitową, więc nie ma sensu uzyskiwać więcej niż 4 bajty/dev/urandom
.Aby wygenerować losową zmienną całkowitą z przedziału od 5 do 10 (włączając obie), użyj
%
działa jako operator modulo.Prawdopodobnie istnieją lepsze sposoby konwersji zmiennej losowej
$RANDOM
na określony zakres. Nie używaj tego do aplikacji kryptograficznych lub w przypadkach, gdy potrzebujesz prawdziwych, losowo rozmieszczonych zmiennych losowych (np. Do symulacji).źródło
# echo $(( $RANDOM % 256 ))
stworzy „losową” liczbę od 0 do 255 w nowoczesnych dialektach * sh.źródło
Być może
UUID
(w systemie Linux) można użyć losowej liczbyAby uzyskać losową liczbę między
70
a100
źródło
Spowoduje to wygenerowanie 8-cyfrowej liczby szesnastkowej.
źródło
Aby pozostać całkowicie w bashu i użyć zmiennej $ RANDOM, ale unikać nierównomiernego rozkładu:
Ten przykład podaje losowe liczby od 20 do 29.
źródło
$r
należy zainicjować na 65535 lub inną wysoką wartość, aby uniknąć[: -lt: unary operator expected
błędu.Dystrybucja jest dobra:
dla ((i = 1; i <= 100000; i ++)) wykonaj echo $ ((RANDOM% (20-10 + 1) + 10)); zrobione | sort -n | uniq -c
policzyć wartość
9183 10
9109 11
8915 12
9037 13
9100 14
9138 15
9125 16
9261 17
9088 18
8996 19
9048 20
źródło