4

我需要一个方法,它返回从最小值到最大值的随机数,包括两个数字。我在文章.NET Matters: Tales from the CryptoRandom from the CryptoRandom from Stephen Toub 和 Shawn Farkas 中找到了一些代码,其中的方法如下所示:

// Note - maxValue is excluded!
public static int GetRandomIntBetween(int minValue, int maxValue)
{
    if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
    if (minValue == maxValue) return minValue;

    var rng = new RNGCryptoServiceProvider();
    var uint32Buffer = new byte[4];
    long diff = maxValue - minValue;

    while (true)
    {
        rng.GetBytes(uint32Buffer);
        uint rand = BitConverter.ToUInt32(uint32Buffer, 0);
        const long max = (1 + (long)int.MaxValue);
        long remainder = max % diff;
        if (rand < max - remainder)
        {
            return (int)(minValue + (rand % diff));
        }
    }
}

我尝试使 maxValue 包含在内:

public static int GetRandomIntBetween(int minValue, int maxValue)
{
    if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
    if (minValue == maxValue) return minValue;

    // Make maxValue inclusive.
    maxValue++;

    var rng = new RNGCryptoServiceProvider();
    var uint32Buffer = new byte[4];
    long diff = maxValue - minValue;

    while (true)
    {
        rng.GetBytes(uint32Buffer);
        uint rand = BitConverter.ToUInt32(uint32Buffer, 0);
        const long max = (1 + (long)int.MaxValue);
        long remainder = max % diff;
        if (rand < max - remainder)
        {
            return (int)(minValue + (rand % diff));
        }
    }
}

看起来很奇怪,但似乎我可以保持前两个检查原样,即使语义略有不同,它仍然有效。结果数据看起来也不错。我错过了什么还是我的改变可以吗?

PS - 我问这个是因为生成随机数显然是一件非常微妙的事情,并且想确保我的方法是正确的。

4

2 回答 2

2

看看我的解决方案(点击那里)

您可以向该类添加其他方法:

public int NextInclusive(int minValue, int maxValue) {
        return Next(minValue, maxValue + 1);
}
于 2013-06-04T00:20:25.130 回答
1

您的更改是正确的,afaik 之间的随机整数是 .之间[a,b]的随机整数[a,b+1[

只要 maxValue 不是 int.MaxValue,那么 ++ 就会溢出,所以不更改 maxValue 并将更改移动到 diff 的计算中会更安全:

long diff = (long)maxValue - minValue + 1;

但是,原函数中的第二次检查显然是错误的,如果minValue == maxValue,返回的 minValue 不是 minValue 和 maxValue 之间的唯一值。

于 2013-02-18T12:14:00.103 回答