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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With