RNGCryptoServiceProvider:生成范围为[0,randomMax)的随机数 [英] RNGCryptoServiceProvider: generate random numbers in the range [0, randomMax)

查看:144
本文介绍了RNGCryptoServiceProvider:生成范围为[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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆