【问题标题】:How "good" is this method for generating random numbers?这种生成随机数的方法有多“好”?
【发布时间】:2013-05-13 01:31:05
【问题描述】:

我在 google 上搜索 RNGCryptoServiceProvider 并提供有关如何限制 Max 和 Min 之间范围的示例,并且仍然获得均匀分布。在我使用模运算符之前,但有时我会得到奇怪的值(高于最大值)...... 无论如何,每次调用该方法时,此代码(归功于未知)使用来自 RNGCCryptoServiceProvider 的新种子随机播种。你们有什么感想?

public static int GetRandom(int min, int max)
{
  byte[] b = new byte[sizeof(int)];
  new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
  int i = BitConverter.ToInt32(b, 0);
  Random r = new Random(i);
  return r.Next(min, max);
}

【问题讨论】:

  • 每次调用 rng 时都重新播种是不好的做法。
  • 好的,那我如何只从 rng 启动一个种子?

标签: c# random cryptography rngcryptoserviceprovider


【解决方案1】:

使用加密类随机生成器作为常规随机生成器的种子是没有意义的。 (根据最薄弱环节的原则......)只需使用随机生成器的单个实例,并重用它:

private static Random rnd = new Random();

public static int GetRandom(int min, int max) {
  return rnd.Next(min, max);
}

【讨论】:

  • 嗯,我希望它可以改进 Random.Next(),因为它非常方便,即使是一周。
  • 标准Random 仅在您将其用于密码学或需要很长时间(例如在线扑克游戏)时才会发挥作用。否则没关系。
  • @MatthewWatson 好的,那我就坚持下去
【解决方案2】:

您需要创建一次RNGCryptoServiceProvider 对象,然后在每次需要新的随机数时重新使用该对象。例如,您可以将所述对象传递到您的 GetRandom() 方法中,也可以将其存储在类级字段中。

RNGCryptoServiceProvider 类型本身而言,它会自行生成良好的数字,无需创建Random 对象并传入种子。这应该会给你一个非常体面的分布:

public static int GetRandom(RNGCryptoServiceProvider rngProvider, int min, int max)
{
    byte[] b = new byte[sizeof(UInt32)];
    rngProvider.GetBytes(b);
    double d = BitConverter.ToUInt32(b, 0) / (double)UInt32.MaxValue;
    return min + (int)((max - min) * d);
}

【讨论】:

  • 谢谢!我会试试这个!
  • 如果 max - min 太大而不能包含在 int 中,则此实现中存在整数溢出。
【解决方案3】:

在您的应用程序中只播种一次随机数生成器是一种更好的做法。 我建议您为随机数生成创建一个静态类。随机生成对象可以通过正常使用产生均匀分布。我不知道用 RNGCryptoServiceProvider 播种生成器有什么好处。我更喜欢像往常一样使用时间作为播种方法。因此以下代码是我的建议:

int randomNumber=Rand.get(min,max);

public static class Rand
{
    private static Random rnd;
    static rand()
    {
        rand=new Random(DateTime.Now.Ticks);
    }
    public static int get(int min,int max)
    {
        return rnd.Next(min,max);
    }
}

【讨论】:

    猜你喜欢
    • 2013-03-26
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多