Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在运行时生成随机数?_C#_Algorithm_Programming Languages_Random - Fatal编程技术网

C# 如何在运行时生成随机数?

C# 如何在运行时生成随机数?,c#,algorithm,programming-languages,random,C#,Algorithm,Programming Languages,Random,既然计算机不能拾取随机数(可以吗?),那么这个随机数实际上是如何生成的。例如在C#中,我们说 里面发生了什么?您可以结账。NET中使用的具体实现是基于Donald E.Knuth的减法随机数生成器算法。有关更多信息,请参阅。随机类是一个 它基本上是一个非常长但确定的重复序列。“随机性”来自于从不同的位置开始。指定从何处开始是通过为随机数生成器选择a来完成的,例如,可以通过使用系统时间或从另一个随机源获取随机种子来完成。将系统时间用作种子 用于生成数字序列的实际算法记录在: Random类的当前实

既然计算机不能拾取随机数(可以吗?),那么这个随机数实际上是如何生成的。例如在C#中,我们说


里面发生了什么?

您可以结账。NET中使用的具体实现是基于Donald E.Knuth的减法随机数生成器算法。有关更多信息,请参阅。

随机类是一个

它基本上是一个非常长但确定的重复序列。“随机性”来自于从不同的位置开始。指定从何处开始是通过为随机数生成器选择a来完成的,例如,可以通过使用系统时间或从另一个随机源获取随机种子来完成。将系统时间用作种子

用于生成数字序列的实际算法记录在:

Random类的当前实现基于Donald E.Knuth的减法随机数生成器算法。有关更多信息,请参见D.E.Knuth。“计算机编程艺术,第2卷:半数值算法”。艾迪生·卫斯理,雷丁,硕士,第二版,1981年


我不知道太多的细节,但我知道的是,一个种子被用来生成随机数,然后基于使用该种子的某种算法,一个新的数被获得

如果你得到基于同一种子的随机数,它们通常是相同的。

计算机使用。本质上,它们的工作方式是从一个种子数开始,每次需要一个新的伪随机数时,通过一个算法对其进行迭代

这个过程当然是完全确定的,因此每次使用一个给定的种子时,它都会生成完全相同的数字序列,但是生成的数字会形成一个统计上的均匀分布(近似),这是很好的,因为在大多数情况下,您所需要的只是随机性

通常的做法是使用当前系统时间作为种子,但如果需要更高的安全性,可以从物理源(如磁盘延迟)收集“熵”,以生成更难预测的种子。在本例中,您还需要使用一个,例如

因为计算机不能随机选择数字(可以吗?)

正如其他人所指出的,“随机”实际上是伪随机的。回答你的附加问题:是的,计算机可以选择真正的随机数。这样做比伪随机数生成器的简单整数算法要昂贵得多,而且通常不需要。然而,有些应用程序必须具有不可预测的真实随机性:密码学和在线扑克会立即浮现在脑海中。如果其中一个使用可预测的伪随机性源,那么攻击者可以更容易地解密/伪造消息,骗子可以找出谁手中有什么

NETCrypto类有一个或多个游戏,钱就在上面。至于它们是如何工作的:关于加密强度随机性的文献非常广泛;有关详细信息,请查阅任何优秀的大学本科密码学教科书


还存在获取随机位的专用硬件。如果您需要从大气噪声中提取随机数,请访问www.random.org

Knuth很好地涵盖了随机性的主题

我们不是很了解随机性。可预测的事物怎么可能是随机的?然而,通过统计测试,伪随机序列似乎是完全随机的

有三类随机发生器,对上面的评论进行了补充

首先,你有伪随机数生成器,如果你知道当前的随机数,很容易计算下一个。这样,如果你发现了一些数字,就很容易对其他数字进行反向工程

然后,有一些加密算法使得这变得更加困难。我相信它们仍然是伪随机序列(与上面的评论相反),但具有一个非常重要的特性,即知道序列中的一些数字并不意味着知道如何计算其余的数字。它的工作方式是加密例程倾向于散列数字,因此,如果一个位发生变化,那么每个位都有可能因此发生变化

考虑一个简单的模生成器(类似于C rand()中的一些实现)

int rand(){ 返回种子=种子*m+a; }

如果m=0,a=0,这是一个周期为1:0,0,0,0,…,的糟糕生成器。。。。 如果m=1和a=1,它看起来也不是很随机:0,1,2,3,4,5,6

但是如果你选择m和a作为2^16左右的素数,如果你随便检查一下,这会看起来非常随机。但是因为这两个数字都是奇数,你会看到低位会切换,即数字交替为奇数和偶数。不是一个伟大的随机数发生器。由于32位数字中只有2^32个值,根据定义,最多迭代2^32次后,您将再次重复该序列,这表明生成器不是随机的

如果你认为中间的位元是好的并且是加扰的,而较低的位元不是随机的,那么你可以用其中的一些位元构造一个更好的随机数生成器,将不同的位元异或在一起,这样所有的位元都能被很好地覆盖。比如:

(rand1()>>8)^rand2()^(rand3()>5)

尽管如此,每个数字都在同步翻转,这使得这是可以预测的。如果你得到两个连续的值,它们是相关的,所以如果你绘制它们,你会在屏幕上看到线条。现在,假设您拥有组合生成器的规则,以便顺序值不是下一个值。 比如说

v1=rand1()>>8^rand2()。。。 v2=rand2()>>8^rand5()

想象一下,种子并不总是在前进。现在,你开始做一些基于逆向工程的更难预测的东西,而且序列更长

例如,如果每次计算rand1(),但仅计算
Random.Next()