เอกสาร Bash บอกว่าทุกครั้งที่$RANDOM
มีการอ้างอิงจะมีการส่งคืนตัวเลขสุ่มระหว่าง 0 ถึง 32767 หากเรารวมการอ้างอิงสองรายการติดต่อกันเราจะได้รับค่าตั้งแต่ 0 ถึง 65534 ซึ่งครอบคลุมช่วงความเป็นไปได้ 63001 ที่ต้องการสำหรับตัวเลขสุ่มระหว่าง 2000 ถึง 65000
หากต้องการปรับให้เข้ากับช่วงที่แน่นอนเราใช้ผลรวมโมดูโล 63001 ซึ่งจะให้ค่าเราตั้งแต่ 0 ถึง 63000 ซึ่งจะต้องเพิ่มขึ้นอีก 2,000 เพื่อให้ได้ตัวเลขสุ่มที่ต้องการระหว่าง 2000 ถึง 65000 สรุปดังนี้
port=$((((RANDOM + RANDOM) % 63001) + 2000))
การทดสอบ
# 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
ความถูกต้องของการคำนวณ
นี่คือการทดสอบแบบเต็มกำลังดุร้ายสำหรับความถูกต้องของการคำนวณ โปรแกรมนี้พยายามสร้างความเป็นไปได้ที่แตกต่างกันทั้งหมด 63001 รายการโดยใช้การคำนวณภายใต้การทดสอบ --jobs
พารามิเตอร์ควรจะทำให้มันทำงานได้เร็วขึ้น แต่ก็ไม่ได้กำหนด (รวมของความเป็นไปได้ที่สร้างขึ้นอาจจะต่ำกว่า 63,001)
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
เป็นที่จะเกิดขึ้นทั้งหมด 63001 ครั้งผมเชื่อว่าเราสามารถใช้นิพจน์ด้านล่างนี้ได้ ยกตัวอย่างเช่นที่นี่คือการคำนวณหามากขึ้นน่าจะเป็นมากกว่า 1/2และที่นี่สำหรับมากกว่า 9/10
shuf
ค่อนข้างเร็ว ๆ นี้ - ฉันเคยเห็นมันในระบบ Ubuntu ในช่วงสองสามปีที่ผ่านมา แต่ไม่ใช่ RHEL / CentOS ปัจจุบัน