Search code examples
c#randomcryptographyrngcryptoserviceprovider

How "good" is this method for generating random numbers?


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 operator, but sometimes it I get strange values (above Max)... Anyways this code (credit to unknown) seeds Random with a new seed from RNGCCryptoServiceProvider, everytime the method is called. What do you guys think?

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);
}

Solution

  • 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);
    }