Yanıtlar:
Kullanın $RANDOM. Genellikle basit kabuk aritmetiği ile birlikte kullanışlıdır. Örneğin, 1 ile 10 arasında (dahil) rastgele bir sayı oluşturmak için:
$ echo $((1 + RANDOM % 10))
3
Gerçek jeneratör variables.cfonksiyonda brand(). Eski versiyonlar basit bir lineer jeneratördü. Sürüm 4.0, 1985 kağıdına atıfta bulunan bashbir jeneratör kullanıyor , bu muhtemelen sahte bir sayıların iyi bir kaynağı olduğu anlamına geliyor. Ben bir simülasyon için (ve kesinlikle kripto için) kullanmazdım, ama muhtemelen temel komut dosyası görevleri için yeterli.
Kullanabileceğiniz ciddi rasgele sayılar gerektiren bir şey yapıyorsanız /dev/randomveya /dev/urandomvarsa:
$ dd if=/dev/urandom count=4 bs=1 | od -t d
$RANDOM % 10, 8 ve 9 da, eğer, ölçülebilir (gerçi sınırlı olarak) 0-7 den daha az olasıdır $RANDOMrastgele veri sağlam bir kaynağıdır.
$RANDOMbireyin aralıktır 0-32767numaraları 0- 7eşleme 3277farklı olası girişler, ancak 8ve 9ancak üretilebilir 3276farklı yollar (çünkü 32768ve 32769mümkün değildir). Bu, hızlı saldırılar için küçük bir sorundur, ancak sonucun düzgün bir şekilde rastgele olmadığı anlamına gelir. Java gibi rastgele kütüphaneler, Randombölünemez bir sayıyı değiştirmek yerine belirli aralıkta düzgün bir rastgele sayı döndürmek için işlevler sunar.
Lütfen bakınız $RANDOM:
$RANDOM0 - 32767 aralığındaki bir sahte tamsayı döndüren dahili bir Bash işlevidir (sabit değil). Bir şifreleme anahtarı oluşturmak için kullanılmamalıdır.
32767herhangi bir özel anlamı vardır?
32767, 2^16 / 2 - 1işaretli bir 16 bit tam sayı için üst sınırdır.
2^15 - 1musun? Eşdeğer, bu yüzden sadece eksik olduğum bir bağlam olup olmadığını merak ediyorum?
Ayrıca shuf kullanabilirsiniz (coreutils'te bulunur).
shuf -i 1-100000 -n 1
shuf -i 1-10 -n 1: syntax error in expression (error token is "1-10 -n 1")
$varAralık sonu yerine şunu ekleyin :var=100 && shuf -i 1-${var} -n 1
-n. Örneğin , 1 ile 100 arasında 5 rasgele sayı oluşturun :shuf -i 1-100 -n 5
shuf -i 1-10 -n 10size 1-10 exactl itibaren tüm numaraları alacak. Eğer belirtirseniz -n 15, sadece bu 10 rakamı tam olarak bir kez alırsınız. Bu gerçekten sadece karışıktır, rastgele sayılar üretmez.
Bunu kabuğunuzdan deneyin:
$ od -A n -t d -N 1 /dev/urandom
Burada, -t dçıktı biçiminin ondalık olarak imzalanması gerektiğini belirtir; -N 1bir bayt okumayı söylüyor /dev/urandom.
od -A n -t d -N 1 /dev/urandom |tr -d ' '
awk'den rastgele sayı da alabilirsiniz
awk 'BEGIN {
# seed
srand()
for (i=1;i<=1000;i++){
print int(1 + rand() * 100)
}
}'
srand()Tohumun mevcut CPU zamanı olduğunu belirtmekte fayda var . Belirli bir tohum belirtmeniz gerekiyorsa, RNG çoğaltılabilir, tohumun srand(x)nerede xolduğunu kullanın . Ayrıca, GNU awk'ın sayısal işlev kılavuzundan alıntılanan "farklı awk uygulamaları dahili olarak farklı rasgele sayı üreteçleri kullanır." Sonuç olarak, istatistiksel dağıtım oluşturmakla ilgileniyorsanız, bir çalışma zamanından diğerine farklı platformlarda (hepsi çalışıyor awkveya çalışıyor gawk) küçük değişiklikler beklemelisiniz .
$ RANDOM var. Nasıl çalıştığını tam olarak bilmiyorum. Ama işe yarıyor. Test için şunları yapabilirsiniz:
echo $RANDOM
Bu numarayı seviyorum:
echo ${RANDOM:0:1} # random number between 1 and 9
echo ${RANDOM:0:2} # random number between 1 and 99
...
${RANDOM:0:1}size 1 veya 2 vermek için% 67.8 şansı var, ${RANDOM:0:2}sadece% 0.03 oranında size tek haneli bir numara verme şansı var (% 1 olmalı) ve her ikisinin de% 0.003 oranında 0 verme şansınız var. Bunun hala iyi olduğu durumlar vardır (örn. Tutarlı olmayan girdi).
0 ile 9 arasında rastgele sayı.
echo $((RANDOM%10))
$RANDOM"0'dan 32767'ye kadar gider." Çoğunlukla 1 ile 3 arasında, birkaç kanatlı rastgele sayı ";)
Bir linux sistemi kullanıyorsanız / dev / random'den rastgele bir sayı veya / dev / urandom'dan . Yeterli rasgele sayılar yoksa dikkatli olun / dev / random bloke olur. Rasgelelik üzerinde hıza ihtiyacınız varsa / dev / urandom kullanın.
Bu "dosyalar", işletim sistemi tarafından oluşturulan rasgele sayılarla doldurulur. Doğru veya sahte rasgele sayılar alırsanız, sisteminize / dev / random uygulamasına bağlıdır. Fare, sabit sürücü, ağ gibi aygıt sürücülerinden toplanan gürültü ile gerçek rasgele sayılar oluşturulur.
Sen ile dosyadan rasgele sayılar alabilirsiniz gg
Bu fikirlerden birkaçını aldım ve çok sayıda rastgele sayı gerekiyorsa hızlı bir şekilde çalışması gereken bir işlev yaptım.
odÇok sayıda rastgele sayıya ihtiyacınız varsa arama yapmak pahalıdır. Bunun yerine bir kez ararım ve / dev / urandom'dan 1024 rasgele sayı kaydederim. Ne zamanrand , son rasgele sayı döndürülür ve ölçeklendirilir. Daha sonra önbellekten kaldırılır. Önbellek boş olduğunda, başka bir 1024 rasgele sayı okunur.
Misal:
rand 10; echo $RET
0 ile 9 (dahil) arasında RET cinsinden rastgele bir sayı döndürür.
declare -ia RANDCACHE
declare -i RET RAWRAND=$(( (1<<32)-1 ))
function rand(){ # pick a random number from 0 to N-1. Max N is 2^32
local -i N=$1
[[ ${#RANDCACHE[*]} -eq 0 ]] && { RANDCACHE=( $(od -An -tu4 -N1024 /dev/urandom) ); } # refill cache
RET=$(( (RANDCACHE[-1]*N+1)/RAWRAND )) # pull last random number and scale
unset RANDCACHE[${#RANDCACHE[*]}-1] # pop read random number
};
# test by generating a lot of random numbers, then effectively place them in bins and count how many are in each bin.
declare -i c; declare -ia BIN
for (( c=0; c<100000; c++ )); do
rand 10
BIN[RET]+=1 # add to bin to check distribution
done
for (( c=0; c<10; c++ )); do
printf "%d %d\n" $c ${BIN[c]}
done
GÜNCELLEME: küçük N. 32 rasgele sayı bit (bu durumda) belirten birlikte kullanılırsa bu aynı zamanda rastgele bit boşa tüm N. için çok iyi çalışmaz 0 ve 9 (10 * arasında 9 rastgele sayılar için yeterli entropiye sahiptir 9 = 1,000,000,000 <= 2 * 32) her 32 rastgele kaynak değerinden birden fazla rasgele sayı çıkarabiliriz.
#!/bin/bash
declare -ia RCACHE
declare -i RET # return value
declare -i ENT=2 # keep track of unused entropy as 2^(entropy)
declare -i RND=RANDOM%ENT # a store for unused entropy - start with 1 bit
declare -i BYTES=4 # size of unsigned random bytes returned by od
declare -i BITS=8*BYTES # size of random data returned by od in bits
declare -i CACHE=16 # number of random numbers to cache
declare -i MAX=2**BITS # quantum of entropy per cached random number
declare -i c
function rand(){ # pick a random number from 0 to 2^BITS-1
[[ ${#RCACHE[*]} -eq 0 ]] && { RCACHE=( $(od -An -tu$BYTES -N$CACHE /dev/urandom) ); } # refill cache - could use /dev/random if CACHE is small
RET=${RCACHE[-1]} # pull last random number and scale
unset RCACHE[${#RCACHE[*]}-1] # pop read random number
};
function randBetween(){
local -i N=$1
[[ ENT -lt N ]] && { # not enough entropy to supply ln(N)/ln(2) bits
rand; RND=RET # get more random bits
ENT=MAX # reset entropy
}
RET=RND%N # random number to return
RND=RND/N # remaining randomness
ENT=ENT/N # remaining entropy
};
declare -ia BIN
for (( c=0; c<100000; c++ )); do
randBetween 10
BIN[RET]+=1
done
for c in ${BIN[*]}; do
echo $c
done
od -An -tu4 -N40 /dev/urandomboşlukla ayrılmış 10 rastgele imzasız 32 bit tam sayı üretecektir. bir dizide saklayabilir ve daha sonra kullanabilirsiniz. kodunuz aşırıya kaçmış gibi görünüyor.
/ Dev / random veya / dev / urandom karakter özel dosyalarından okumak yoludur.
Bu cihazlar okunduğunda gerçekten rasgele sayılar döndürür ve uygulama yazılımının şifreleme için güvenli anahtarlar seçmesine yardımcı olmak üzere tasarlanmıştır. Bu rastgele sayılar, çeşitli rasgele olayların katkıda bulunduğu bir entropi havuzundan çıkarılır. {LDD3, Jonathan Corbet, Alessandro Rubini ve Greg Kroah-Hartman]
Bu iki dosya özellikle çekirdek rasgeleleştirmesi için arabirimdir
void get_random_bytes_arch(void* buf, int nbytes)
bu işlev, donanımın uygulandığı (genellikle) olan donanımdan gerçekten rasgele bayt çeker veya entropi havuzundan (fare ve klavye kesintileri gibi olaylar ve SA_SAMPLE_RANDOM'a kayıtlı diğer kesintiler arasındaki zamanlamalardan oluşur).
dd if=/dev/urandom count=4 bs=1 | od -t d
Bu çalışır, ancak ddstdout için gereksiz çıktı yazar . Aşağıdaki komut sadece ihtiyacım olan tamsayıyı veriyor. Hatta aritmetik genişleme verilen bitmask ayarlayarak ihtiyacım olduğu gibi rastgele bit belirtilen sayıda alabilirsiniz:
me@mymachine:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump
-d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))
Belki biraz geç kaldım, ama jotBash aralığında bir rastgele sayı oluşturmak için kullanmaya ne dersiniz ?
jot -r -p 3 1 0 1
Bu -r, 3 ondalık basamak hassasiyetine ( -p) sahip rastgele ( ) bir sayı oluşturur . Bu durumda, 0 ile 1 ( 1 0 1) arasında bir sayı alırsınız . Sıralı verileri de yazdırabilirsiniz. El kitabına göre rastgele sayının kaynağı:
Rastgele sayılar hiçbir tohum belirtilmediğinde arc4random (3) ve bir tohum verildiğinde rastgele (3) ile elde edilir.
@Nelson, @Barun ve @Robert'in harika cevaplarına dayanarak, rastgele sayılar üreten bir Bash betiği.
/dev/urandombu da Bash'in yerleşik kodundan çok daha iyidir$RANDOM#!/usr/bin/env bash
digits=10
rand=$(od -A n -t d -N 2 /dev/urandom |tr -d ' ')
num=$((rand % 10))
while [ ${#num} -lt $digits ]; do
rand=$(od -A n -t d -N 1 /dev/urandom |tr -d ' ')
num="${num}$((rand % 10))"
done
echo $num
0 ile n (işaretli 16 bit tam sayı) aralığında rasgele sayı oluşturun. Sonuç $ RAND değişkeninde ayarlandı. Örneğin:
#!/bin/bash
random()
{
local range=${1:-1}
RAND=`od -t uI -N 4 /dev/urandom | awk '{print $2}'`
let "RAND=$RAND%($range+1)"
}
n=10
while [ $(( n -=1 )) -ge "0" ]; do
random 500
echo "$RAND"
done
Bir programın rastgele dallanması veya evet / hayır; 1/0; doğru / yanlış çıktı:
if [ $RANDOM -gt 16383 ]; then # 16383 = 32767/2
echo var=true/1/yes/go_hither
else
echo var=false/0/no/go_thither
fi
16383'ü hatırlamak için tembelseniz:
if (( RANDOM % 2 )); then
echo "yes"
else
echo "no"
fi