alhazen alhazen - 10 days ago 6
C# Question

RNGCryptoServiceProvider: generate random numbers in the range [0, randomMax)

I wrote the following code to generate random numbers in the [0, int.MaxValue) range, but I wasn't sure how to restrict the range to [0, randomMax) while maintaining an even distribution:

private static int GetNextInt32(this RNGCryptoServiceProvider random)
{
var buffer = new byte[sizeof(int)];
random.GetBytes(buffer);
return Math.Abs(BitConverter.ToInt32(buffer, 0));
}


Thanks.

Answer

Here's one way to do it: http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=775. See the section titled "Creating a System.Random Replacement."

Note, however, that using the modulus operator might not be the best way to ensure a good distribution. A possibly better way would be (int)(NextDouble() * (MaxValue - 1));

Your code has a latent bug. If buffer contains the hex values 00 00 00 80, which is int.MinValue, Math.Abs will throw an exception.

Note that calling GetBytes on the RNGCryptoServiceProvider is very slow compared to calling Random.Next. You're better off calling GetBytes to fill a larger buffer, and then dribble the random numbers from it. My example shows how that's done.

Comments