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)];
return Math.Abs(BitConverter.ToInt32(buffer, 0));
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
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.