Bash belgelerine her $RANDOM
gönderme yapıldığında 0 ile 32767 arasında rastgele bir sayı döndürüldüğünü söylüyor . İki ardışık referansı toplarsak, 0 ile 65534 arasında değerler alırız, bu değer 2000 ile 65000 arasında rastgele bir sayı için 63001 olasılık aralığını kapsar.
Tam aralığa ayarlamak için, bize 0 ila 63000 arasında bir değer verecek olan toplam modulo 63001'i kullanıyoruz. Bu da 2000 ve 65000 arasında istenen rasgele sayıyı sağlamak için 2000 yılına kadar bir artışa ihtiyaç duyuyor. aşağıdaki gibi özetlenmiştir:
port=$((((RANDOM + RANDOM) % 63001) + 2000))
Test yapmak
# Generate random numbers and print the lowest and greatest found
test-random-max-min() {
max=2000
min=65000
for i in {1..10000}; do
port=$((((RANDOM + RANDOM) % 63001) + 2000))
echo -en "\r$port"
[[ "$port" -gt "$max" ]] && max="$port"
[[ "$port" -lt "$min" ]] && min="$port"
done
echo -e "\rMax: $max, min: $min"
}
# Sample output
# Max: 64990, min: 2002
# Max: 65000, min: 2004
# Max: 64970, min: 2000
Hesaplamanın doğruluğu
İşte hesaplamanın doğruluğu için tam, kaba kuvvet testi. Bu program sadece test edilen hesaplamayı kullanarak 63001 farklı olasılıkları rastgele oluşturmaya çalışır. --jobs
Parametre daha hızlı çalışmasını sağlamak gerekir, ancak (63001 daha düşük olabilir oluşturulan olasılıklar toplamı) deterministik değil.
test-all() {
start=$(date +%s)
find_start=$(date +%s)
total=0; ports=(); i=0
rm -f ports/ports.* ports.*
mkdir -p ports
while [[ "$total" -lt "$2" && "$all_found" != "yes" ]]; do
port=$((((RANDOM + RANDOM) % 63001) + 2000)); i=$((i+1))
if [[ -z "${ports[port]}" ]]; then
ports["$port"]="$port"
total=$((total + 1))
if [[ $((total % 1000)) == 0 ]]; then
echo -en "Elapsed time: $(($(date +%s) - find_start))s \t"
echo -e "Found: $port \t\t Total: $total\tIteration: $i"
find_start=$(date +%s)
fi
fi
done
all_found="yes"
echo "Job $1 finished after $i iterations in $(($(date +%s) - start))s."
out="ports.$1.txt"
[[ "$1" != "0" ]] && out="ports/$out"
echo "${ports[@]}" > "$out"
}
say-total() {
generated_ports=$(cat "$@" | tr ' ' '\n' | \sed -E s/'^([0-9]{4})$'/'0\1'/)
echo "Total generated: $(echo "$generated_ports" | sort | uniq | wc -l)."
}
total-single() { say-total "ports.0.txt"; }
total-jobs() { say-total "ports/"*; }
all_found="no"
[[ "$1" != "--jobs" ]] && test-all 0 63001 && total-single && exit
for i in {1..1000}; do test-all "$i" 40000 & sleep 1; done && wait && total-jobs
p/q
Oluşturulan 63001 olasılığının tümünün belirli bir olasılığını elde etmek için kaç yineleme gerektiğini belirlemek için , aşağıdaki ifadeyi kullanabileceğimize inanıyorum. Örneğin, burada 1/2'den büyük bir olasılık ve 9/10'dan büyük bir olasılık için hesaplama .
shuf
nispeten yeni - son birkaç yıldır Ubuntu sistemlerinde gördüm ama mevcut RHEL / CentOS'da değil.