【问题标题】:RNGCryptoServiceProvider with both min and max inclusive包含最小值和最大值的 RNGCryptoServiceProvider
【发布时间】:2013-02-18 11:54:47
【问题描述】:

我需要一个方法,它返回从 min 到 max 的随机数,包括两个数字。我在 Stephen Toub 和 Shawn Farkas 的文章 .NET Matters: Tales from the CryptoRandom 中找到了一些代码,其中的方法看起来像这样:

// 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 - 我问这个是因为生成随机数显然是一件非常微妙的事情,并且想确保我的方法是正确的。

【问题讨论】:

    标签: c# random rngcryptoserviceprovider


    【解决方案1】:

    Look at my solution (click there)

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

    public int NextInclusive(int minValue, int maxValue) {
            return Next(minValue, maxValue + 1);
    }
    

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-04
        • 1970-01-01
        • 2018-01-09
        • 2022-01-12
        • 2023-04-02
        • 2017-11-02
        • 1970-01-01
        相关资源
        最近更新 更多