概述
Random类
一说到生成随机数,我们很容易会想到运用Random类,创建一个Random对象,生成自己想要的随机数。然后噼里啪啦就敲出了如下代码:
for (int i = 0; i < 5; i++)
{
Random random = new Random();
Console.WriteLine(random.Next());
}
Console.ReadKey();
于是满心期待着获取五个随机数,甚至都不打算单独输出看看。但当我们将其输出会发现,这五个随机数竟然一模一样!
原来,因为Random只是生成伪随机数,就像官方文档里写的那样:
Random类默认的无参构造函数可以根据当前系统时钟为种子,进行一系列算法得出要求范围内的伪随机数。而在上面的代码中,我们正是用了无参的构造函数,所以在一个很短的时间里,系统生成的种子是一样,所以通过相同的算法算出来的随机数也必然会是一样的。
小知识:C#中生成随机数使用的算法是线性同余法,公式如下:
第N+1个数 = ( 第N个数 * A + B) % M
(A、B、M均是常数)
可以看到,第一个生成的随机数便是需要我们传入的seed,但是在上面代码里,我们每次循环都新建了一个对象,而在极短的时间内,系统提供的seed是一致的。这就直接导致通过上述公式计算出来的随机数一模一样。
如果我们将new Random语句放在循环之外,就可以得到五个不同的随机数。这是因为,我们第一个数是通过系统seed算出来的,而后面的每一个数都是通过前面一个数计算出来的。即公式里第N+1个数与第N个数的关系。
虽然通过这种方法我们得到的随机数看起来很随机了,但毕竟这个算法是伪随机数,当第N个数和因子都相同时,生成的随机数仍然是重复的随机数。这个时候,想要得到真随机数(即完全不一样的随机数),就需要我们每次都传入一个随机的seed,于是便有了通过Guid的方法来生成真随机数。
利用Guid生成真随机数
首先要知道Guid是Globally Unique Identifier的缩写,中文译为全局唯一标识符,也称作 UUID(Universally Unique IDentifier) 。是一种由算法生成的二进制长度为128位的数字标识符。
Guid是在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。
byte[] buffer = Guid.NewGuid().ToByteArray();//将Guid转换为字节数组
int seed = BitConverter.ToInt32(buffer, 0);//利用BitConvert方法把字节数组转换为整数
Random random= new Random(seed);//以这个生成的整数为种子
当然也可以一步到位:
double a = new Random(BitConverter.ToInt32(new Guid().ToByteArray(), 0)).Next(0, 100);
这个跟上面的略微有些差别,不过是对于生成的随机数有进一步的限制而已。比如BitConverter.ToInt32()函数:
再比如Random中的Next()函数,无参或者有参的都有。这里两个参数无疑是规定了上下限的,不过区间是左闭右开。上面代码的范围即是[0,100)的范围。
以上都可以通过点击这里查看官方的文档。这里还有中文的文档~
最后
以上就是激动白云为你收集整理的C#中生成(真or伪)随机数(Random、Guid剖析)的全部内容,希望文章能够帮你解决C#中生成(真or伪)随机数(Random、Guid剖析)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复