Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

random

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.

like image 530
alhazen Avatar asked May 24 '11 14:05

alhazen


1 Answers

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.

like image 150
Jim Mischel Avatar answered Sep 18 '22 22:09

Jim Mischel