Setelah googling sedikit, saya tidak dapat menemukan cara sederhana untuk menggunakan perintah shell untuk menghasilkan bilangan bulat desimal acak yang termasuk dalam rentang tertentu, yaitu antara minimum dan maksimum.
Saya membaca tentang /dev/random
, /dev/urandom
dan $RANDOM
, tetapi tidak ada yang bisa melakukan apa yang saya butuhkan.
Apakah ada perintah lain yang bermanfaat, atau cara untuk menggunakan data sebelumnya?
shell
command-line
command
random
BowPark
sumber
sumber
Jawaban:
Di toolchest POSIX, Anda dapat menggunakan
awk
:Jangan tidak menggunakannya sebagai sumber untuk membuat password atau data rahasia misalnya, seperti kebanyakan
awk
implementasi, jumlah dapat dengan mudah ditebak didasarkan pada waktu yang perintah dijalankan.Dengan banyak
awk
implementasi, perintah yang dijalankan dua kali dalam detik yang sama umumnya akan memberi Anda output yang sama.sumber
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))}'
. Anda bisa menggunakan$RANDOM
alih-alihod ... /dev/random
tetapi kemudian nilai seed Anda dalam kisaran yang relatif kecil dari 0 hingga 32767 dan karenanya Anda mungkin akan mendapatkan pengulangan yang terlihat dalam output Anda dari waktu ke waktu.Anda dapat mencoba
shuf
dari GNU coreutils:sumber
shuf
.mencatat
Pada BSD dan OSX Anda dapat menggunakan jot untuk mengembalikan nomor acak tunggal (
-r
) dari intervalmin
kemax
, inklusif.Masalah distribusi
Sayangnya, jangkauan dan distribusi angka yang dihasilkan secara acak dipengaruhi oleh fakta bahwa jot menggunakan aritmatika floating point presisi ganda secara internal dan printf (3) untuk format output, yang menyebabkan masalah pembulatan dan pemotongan. Oleh karena itu, interval
min
danmax
dihasilkan lebih jarang seperti yang ditunjukkan:Pada OS X 10.11 (El Capitan) ini tampaknya telah diperbaiki:
dan...
Memecahkan masalah distribusi
Untuk versi OS X yang lebih lama, untungnya ada beberapa solusi. Salah satunya adalah menggunakan konversi integer printf (3). Satu-satunya peringatan adalah bahwa interval maksimum sekarang menjadi
max+1
. Dengan menggunakan format integer, kami mendapatkan distribusi yang adil di seluruh interval:Solusi sempurna
Akhirnya, untuk mendapatkan gulungan dadu yang adil menggunakan solusi, kami memiliki:
Pekerjaan rumah ekstra
Lihat jot (1) untuk matematika berdarah dan detail format dan banyak lagi contoh.
sumber
The
$RANDOM
variabel biasanya bukan cara yang baik untuk menghasilkan nilai acak yang baik. Output dari/dev/[u]random
kebutuhan juga harus dikonversi terlebih dahulu.Cara yang lebih mudah adalah dengan menggunakan bahasa tingkat yang lebih tinggi, seperti misalnya python:
Untuk menghasilkan variabel integer acak antara 5 dan 10 (5 <= N <= 10), gunakan
Jangan gunakan ini untuk aplikasi kriptografi.
sumber
Anda bisa mendapatkan nomor acak
urandom
head -200 /dev/urandom | cksum
Keluaran:
3310670062 52870
Untuk mengambil satu bagian dari nomor di atas.
head -200 /dev/urandom | cksum | cut -f1 -d " "
Maka outputnya adalah
3310670062
sumber
head -200
(atau yang setara dengan POSIXhead -n 100
) mengembalikan 200 baris pertama/dev/urandom
./dev/urandom
bukan file teks, perintah itu bisa kembali dari 200 byte (semua yang 0x0a, LF di ASCII) hingga tak terbatas (jika byte 0xa terjadi tidak pernah dikembalikan) tetapi nilai antara 45k dan 55k adalah yang paling mungkin. cksum mengembalikan angka 32bit, jadi tidak ada gunanya untuk mendapatkan lebih dari 4 byte/dev/urandom
.Untuk menghasilkan variabel integer acak antara 5 dan 10 (termasuk keduanya), gunakan
%
bekerja sebagai operator modulo.Mungkin ada cara yang lebih baik untuk mengonversi variabel acak
$RANDOM
ke rentang tertentu. Jangan gunakan ini untuk aplikasi kriptografi atau dalam kasus Anda memerlukan variabel acak yang terdistribusi secara merata (seperti untuk simulasi).sumber
# echo $(( $RANDOM % 256 ))
akan menghasilkan angka "acak" antara 0-255 dalam dialek * sh modern.sumber
Mungkin
UUID
(di Linux) dapat digunakan untuk mengambil nomor acakUntuk mendapatkan nomor acak antara
70
dan100
sumber
Ini akan menghasilkan angka heksadesimal 8 digit.
sumber
Untuk tetap sepenuhnya dalam bash dan gunakan variabel $ RANDOM tetapi hindari distribusi yang tidak merata:
Contoh ini akan memberikan angka acak dari 20 hingga 29.
sumber
$r
harus diinisialisasi ke 65535 atau nilai tinggi lainnya untuk menghindari[: -lt: unary operator expected
kesalahan.Distribusi bagus:
untuk ((i = 1; i <= 100000; i ++)) lakukan echo $ ((RANDOM% (20 - 10 + 1) + 10)); selesai | sort -n | uniq -c
nilai hitung
9183 10
9109 11
8915 12
9037 13
9100 14
9138 15
9125 16
9261 17
9088 18
8996 19
9048 20
sumber