bash脚本随机数不完全随机

时间:2014-03-20 14:53:28

标签: bash random

我需要能够在2013年到2044年之间生成一个随机数(包括在内)。我已经尝试了下面的两个脚本,但在任何一种情况下输出都不是很随机。许多数字都在重复,其他人则丢失了。有办法解决这个问题吗?

这是第一个脚本:

    i="1"
    x="2014"
    y="2044"
    while [ $i != 32 ]; do
            var=$RANDOM
            var=$[ $x + $var % ($y + 1 -$x) ]
            echo $var
            i=$[$i+1]
     done

这是第二个

    i="1"
    while [ $i != 32 ]; do
            var=$(shuf -i 2014-2044 -n1)
            echo $var
            i=$[$i+1]
    done

谢谢, 席亚拉

4 个答案:

答案 0 :(得分:2)

[y,z] x>范围内生成 x 随机数时z-y ,你会有一些重复。您可能还会在连续的插槽中遇到一些重复的数字,因为当您使用mod时,其中一些随机数实际上会映射到相同的数字。如果您增加范围,您会注意到这些数字更多是随机

答案 1 :(得分:2)

这是随机数的本质。让我们试试3100次迭代。我们期望在[2014,2044]中为每个号码获得100个条目:

#!/bin/bash
x=2014
y=2044
n=()
for ((i=1; i<=3100; i++)); do
    (( n[x + RANDOM % (y-x+1)] += 1 ))
done
for ((i=x; i<=y; i++)); do
    printf "%d\t%d\n" $i ${n[i]}
done
2014    95
2015    96
2016    98
2017    87
2018    96
2019    82
2020    111
2021    105
2022    113
2023    100
2024    102
2025    95
2026    89
2027    110
2028    102
2029    93
2030    107
2031    109
2032    115
2033    92
2034    108
2035    96
2036    94
2037    109
2038    91
2039    113
2040    90
2041    123
2042    82
2043    102
2044    95

答案 2 :(得分:0)

由于您需要随机排列,因此您要生成的随机数实际上是 indices 到剩余未选数的列表中。像

这样的东西
unselected=( {2014..2044} )
while (( ${#unselected[@]} > 0 )); do
    # Pick a random index
    index=$(( $RANDOM % ${#unselected[@]} ))
    echo ${unselected[index]}
    # Remove the value at that index
    unset unselected[index]
    unselected=( "${unselected[@]}" )
done

答案 3 :(得分:0)

seq 2014 2044 | sort -R

这会使用seq创建数字范围,然后随机重新排序。