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.c
fonksiyonda brand()
. Eski versiyonlar basit bir lineer jeneratördü. Sürüm 4.0, 1985 kağıdına atıfta bulunan bash
bir 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/random
veya /dev/urandom
varsa:
$ 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 $RANDOM
rastgele veri sağlam bir kaynağıdır.
$RANDOM
bireyin aralıktır 0-32767
numaraları 0
- 7
eşleme 3277
farklı olası girişler, ancak 8
ve 9
ancak üretilebilir 3276
farklı yollar (çünkü 32768
ve 32769
mü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, Random
bö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
:
$RANDOM
0 - 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.
32767
herhangi bir özel anlamı vardır?
32767
, 2^16 / 2 - 1
işaretli bir 16 bit tam sayı için üst sınırdır.
2^15 - 1
musun? 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")
$var
Aralı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 10
size 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 1
bir 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 x
olduğ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 awk
veya ç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/urandom
boş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 dd
stdout 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 jot
Bash 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/urandom
bu 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