How “good” is this method for generating random numbers?

后端 未结 3 2187
别那么骄傲
别那么骄傲 2021-02-11 08:39

I was searching on google for RNGCryptoServiceProvider with examples on how to limit the range between Max and Min, and still get an even distribution. Before I used modulo oper

相关标签:
3条回答
  • 2021-02-11 09:17

    There is no point in using an encryption class random generator to seed a regular random generator. (By the principle of the weakest link...) Just use a single instance of the random generator, and reuse it:

    private static Random rnd = new Random();
    
    public static int GetRandom(int min, int max) {
      return rnd.Next(min, max);
    }
    
    0 讨论(0)
  • 2021-02-11 09:22

    You'll want to create your RNGCryptoServiceProvider object once and then re-use that object every time you want a new random number. For instance, you can either pass said object into your GetRandom() method or store it in a class-level field.

    As far as the RNGCryptoServiceProvider type itself, it generates good numbers on its own, there's no need to create a Random object and pass in a seed. This should give you a very decent distribution:

    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);
    }
    
    0 讨论(0)
  • 2021-02-11 09:26

    It's a better practice to seed your random number generator just one time in your application. I suggest you create a static class for random number generation. The random generation object can yield even distribution just by normal usage. I don't know whats the benefit of seeding the generator with RNGCryptoServiceProvider. I prefer using the time as seeding method as usual. Therefore the following code is my suggestion:

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题