RNGCryptoServiceProvider:生成范围为[0,randomMax)的随机数 [英] RNGCryptoServiceProvider: generate random numbers in the range [0, randomMax)
问题描述
我编写了以下代码来生成[0,int.MaxValue)范围内的随机数,但是我不确定如何在保持均匀分布的同时将范围限制为[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));
}
谢谢.
推荐答案
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."
但是,请注意,使用模运算符可能不是确保良好分布的最佳方法.可能更好的方法是(int)(NextDouble() * (MaxValue - 1));
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));
您的代码有潜在的错误.如果buffer
包含十六进制值00 00 00 80
,即int.MinValue
,则Math.Abs
将引发异常.
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.
请注意,与调用Random.Next
相比,在RNGCryptoServiceProvider
上调用GetBytes
的速度非常慢.最好不要调用GetBytes
来填充更大的缓冲区,然后从中运出随机数.我的示例显示了如何完成此操作.
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.
这篇关于RNGCryptoServiceProvider:生成范围为[0,randomMax)的随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!