Насколько "хорош" этот метод для генерации случайных чисел?

Я искал в google RNGCryptoServiceProvider с примерами того, как ограничить диапазон между Максом и Минутом, и получить равномерное распределение. Раньше я использовал оператор по модулю, но иногда я получаю странные значения (выше Max)... В любом случае этот код (кредит неизвестен) порождает Random с новым семенем из 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);
}

3 ответа

Решение

Вы хотите создать свой 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);
}

Нет смысла использовать генератор случайных чисел класса шифрования для заполнения обычного генератора случайных чисел. (По принципу самого слабого звена...) Просто используйте один экземпляр генератора случайных чисел и используйте его повторно:

private static Random rnd = new Random();

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

Лучше всего использовать генератор случайных чисел только один раз в приложении. Я предлагаю вам создать статический класс для генерации случайных чисел. Случайный объект генерации может дать равномерное распределение только при обычном использовании. Я не знаю, каково преимущество заполнения генератора с помощью 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);
    }
}
Другие вопросы по тегам