Tài liệu Bash nói rằng mỗi lần $RANDOM
được tham chiếu, một số ngẫu nhiên trong khoảng từ 0 đến 32767 được trả về. Nếu chúng tôi tổng hợp hai tham chiếu liên tiếp, chúng tôi nhận được các giá trị từ 0 đến 65534, bao gồm phạm vi mong muốn là 63001 khả năng cho một số ngẫu nhiên trong khoảng từ 2000 đến 65000.
Để điều chỉnh nó đến phạm vi chính xác, chúng tôi sử dụng tổng modulo 63001, sẽ cung cấp cho chúng tôi một giá trị từ 0 đến 63000. Điều này đến lượt nó chỉ cần tăng thêm 2000 để cung cấp số ngẫu nhiên mong muốn, trong khoảng từ 2000 đến 65000. Điều này có thể là tóm tắt như sau:
port=$((((RANDOM + RANDOM) % 63001) + 2000))
Kiểm tra
# 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
Tính chính xác của phép tính
Dưới đây là một bài kiểm tra đầy đủ, vũ phu cho tính chính xác của phép tính. Chương trình này chỉ cố gắng tạo ngẫu nhiên tất cả 63001 khả năng khác nhau, sử dụng phép tính được kiểm tra. Các --jobs
tham số nên làm cho nó chạy nhanh hơn, nhưng nó không xác định (tổng cộng khả năng tạo ra có thể thấp hơn 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
Để xác định có bao nhiêu lần lặp là cần thiết để có xác suất nhất định cho p/q
tất cả 63001 khả năng đã được tạo, tôi tin rằng chúng ta có thể sử dụng biểu thức bên dưới. Ví dụ, đây là phép tính cho xác suất lớn hơn 1/2 và ở đây lớn hơn 9/10 .
shuf
là tương đối gần đây - tôi đã thấy nó trên các hệ thống Ubuntu trong vài năm qua nhưng không phải là RHEL / CentOS hiện tại.