问题

计算机随机生成一个数是不是真的是随机的?

回答
这个问题很有意思,也触及了计算机科学中最基础也最核心的原理之一。简单来说,计算机生成的随机数,并不是真正意义上的“随机”。

咱们一步步来聊聊这个话题,尽量说得通俗易懂。

什么是真正的“随机”?

想象一下,你在玩石头剪刀布。你的选择是随机的,对吧?你不会提前想好,也不会有任何规律可循。即使你每次都出“石头”,别人也无法预测你下一次会出什么。这种完全不可预测性,不受任何已知因素影响的性质,可以算是一种真正的随机。

再或者,想象一下一个纯粹的物理过程,比如放射性物质衰变。你无法预测下一个原子什么时候会衰变,也无法控制它的衰变行为。这种由物理世界的内在不确定性带来的随机性,也是我们理解的真正的随机。

计算机的本质:确定性

现在咱们再看看计算机。计算机本质上是一个非常精确的“指示执行者”。它严格按照程序员写好的指令,一步一步地执行。每一条指令,在给定的状态下,都会产生一个确定的结果。打个比方,就像一个非常非常听话的机器人,你告诉它“走一步”,它就一定会走一步;你告诉它“把这个数字加二”,它就会老老实实地加二。

那么,计算机怎么生成“随机数”呢?

既然计算机是确定性的,它怎么能变出“不确定”的随机数呢?这就需要我们引入一个概念:伪随机数生成器(PseudoRandom Number Generator, PRNG)。

PRNG 就像是一个非常有规律的“魔术师”。它并不是真的从无中生有地变出随机数,而是利用一个初始的“种子”(seed),通过一套非常精密的数学算法,计算出一连串看似随机的数字。

这个“种子”非常关键。如果你用相同的种子启动同一个PRNG,它就会生成一模一样的“随机”数列。就好像你给魔术师一个特定的道具,他用这个道具就能变出特定的戏法,下次你再给他同样的道具,他还是能变出同样的戏法。

伪随机数的特点

PRNG 生成的数字之所以叫做“伪”随机,是因为它们具备一些“看起来像”随机数的特性:

1. 统计学上的随机性: 这是一般PRNG最追求的。它们生成的数字在统计学意义上看起来很随机。比如,在生成的数字序列中,出现偶数和奇数的概率接近一半;出现的0到9的数字概率也大致均等;如果把这些数字画成图,它们会均匀地散布开,而不是聚集在某个区域。这是通过精心设计的算法来实现的。

2. 不可预测性(在一定程度上): 对于知道其算法和当前状态(例如,知道当前的种子)的观察者来说,下一个数是完全可预测的。但是,对于不知道这些信息的人来说,要从已知的数列中猜出下一个数,或者推算出生成它的种子,是极其困难的,需要大量的计算。

3. 周期性: 所有的PRNG都有一个“周期”。也就是说,经过一定数量的生成后,它会重新开始重复之前的数列。这个周期有多长,是衡量一个PRNG好坏的重要标准。好的PRNG周期非常非常长,长到我们通常使用的计算机程序跑完一生也碰不到它重复。

常见的PRNG算法

有很多种算法可以生成伪随机数,举几个例子:

线性同余生成器 (Linear Congruential Generator, LCG): 这是最古老也最简单的一种。它的公式大概是:X_(n+1) = (a X_n + c) mod m。其中,X_n是当前的数,X_(n+1)是下一个数,a, c, m是预设的常数。虽然简单,但它的周期和统计特性并不总是很理想,现在很多地方已经不使用了,或者只在对随机性要求不高的场合使用。

Mersenne Twister (梅森旋转算法): 这是目前非常流行且广泛使用的一种PRNG。它有一个极长的周期(2^19937 1,这是一个非常大的数字),并且在统计学上表现也相当不错,因此在很多模拟和科学计算领域被广泛采用。

为什么我们通常认为计算机生成的随机数够用了?

虽然它们是“伪”随机的,但对于大多数应用场景来说,它们已经足够了。

游戏: 玩游戏,比如打牌、掷骰子,你不需要绝对的随机。只要足够“看起来随机”,不让玩家轻易预测,游戏体验就足够了。
模拟实验: 在科学研究中,需要大量的随机数来模拟各种现象。只要PRNG的统计特性好,并且周期足够长,就可以得到可靠的实验结果。
密码学: 在密码学领域,对随机性的要求就非常高了。如果一个密码系统的随机数生成器不够随机,那么整个系统的安全性就会受到威胁。

那有没有更“真”的随机数呢?

有,但需要借助物理世界的随机性。这叫做真随机数生成器 (True Random Number Generator, TRNG),也叫硬件随机数生成器。

TRNGs 通常会利用一些难以预测的物理现象来产生随机数,例如:

热噪声: 电子元件在工作时会产生微小的、随机的电压波动,这些噪声就是非常好的随机源。
放射性衰变: 如前面提到的,放射性物质的衰变是不可预测的。
大气噪声: 接收到的无线电波中也包含大量随机噪声。
量子效应: 利用量子力学的固有不确定性,比如光子的随机偏振或量子隧穿效应。

这些物理过程产生的信号,经过放大、数字化处理,就可以变成我们需要的随机数。这类随机数理论上是无法预测的,因此在密码学、安全领域以及一些对随机性要求极高的科学研究中,会优先使用TRNGs。

总结一下:

所以,当你问计算机生成的数是不是真的是随机的,答案是:

不是真正随机的。 它们是通过算法和种子生成的,本质上是确定性的,可以被复制和预测(如果你知道种子和算法)。
但是,它们是“伪随机的”,并且在统计学上表现得非常像随机数。 对于大多数日常应用来说,它们的随机性已经足够满足需求。
需要真正随机数时,我们依赖于物理过程,也就是 TRNGs。

计算机的“随机”之旅,其实是一场巧妙的数学游戏,用确定性的规则,制造出我们感觉上的不确定性。这是一个很有意思的设计,也正是它让很多复杂的技术成为可能。

网友意见

user avatar

随机数可以用硬件弄出来。例如采集环境或者自然界的噪声。但噪声采集也是有带宽(限制)的, 采集到的噪声也很可能是 f^-n 噪声(功率谱密度)而不是期待的白噪声。

俺在以前的散文里面提到一个帮助睡眠的电路, 就可以产生这样的噪声。

您如果把噪声量化成浮点数以后, 某个时刻的浮点数就是个随机数。


噪音源是雪崩管(反接的 B-E 结)或者齐纳管。 Q2 放大输出给音频输入(有源音箱等)。

**雪崩二极管(avalanche diode)在特定反向电压下会雪崩击穿。齐纳二极管也会有类似的效应。雪崩二极管的电压有小的正温度系数,而齐纳二极管则是负温度系数。有精度要求的电压基准用背靠背的结构。

如果您需要更宽的带宽那就需要用微波晶体管了。 自己刷 DIGIKEY 吧。



**这个有点不一样, R1 的热噪声经过 C1 (LPF) 给 OPAMP 放大输出。 OPAMP 可以选用烂贱的 LM324 或者 LM386。


至于伪随机数, 可以用一个例子看看效果。

对了, 下面的代码授权方式是 WTFPL。



客户端网页/屏幕生成视频噪音动图的脚本代码例子


亲测可用。看起来比较好的。


       <html>  <head>  </head>     <body>  <canvas id=myCanvas0 width=1600 height=320></canvas> </body>   <script>        var li_w = myCanvas0.width; var li_h = myCanvas0.height; var lg_ocanvas = document.createElement("canvas");      lg_ocanvas.width  =  li_w<<1;                               lg_ocanvas.height =  li_h<<1;  var lc_Ocontext = lg_ocanvas.getContext("2d", {alpha: false}); var canvas_data = lc_Ocontext.createImageData(lg_ocanvas.width, lg_ocanvas.height); var vbuff = new Uint8Array(canvas_data.data.buffer);     // render noise once, to the offscreen-canvas whitenoise(lc_Ocontext);  // main loop draw the offscreen canvas to random offsets var lc_context = myCanvas0.getContext("2d", {alpha: false}); (function loop() {   var li_x = (li_w * Math.random())|0;                     var li_y = (li_h * Math.random())|0;      lc_context.drawImage(lg_ocanvas, -li_x, -li_y);       requestAnimationFrame(loop) })()  function whitenoise(lc_context) {   var li_len = vbuff.length - 1;   while(li_len--) vbuff[li_len] = Math.random() < 0.5 ? 0 : -1>>0;   lc_context.putImageData(canvas_data, 0, 0); }   </script>  </html>      




Uint8Array 如果改成 Uint32Array 会更酷, 但是在 (linux) GOOGLE CHROME BROWSER 上会失效或者很难看出效果,虽然在 FIREFOX 上很正常。 因此,俺用 Uint8Array 而不是 Uint32Array。



动图效果截图:




比较简短的。


       <html>  <head>  </head>     <body>  <canvas id=myCanvas0 width=1200 height=600></canvas> </body>   <script>    var lc_context0 = myCanvas0.getContext("2d", {alpha:false});  var canvas_data = lc_context0.createImageData(myCanvas0.width, myCanvas0.height);  var vbuffer = new Uint8Array(canvas_data.data.buffer);   (function loop() {   noise(lc_context0);   requestAnimationFrame(loop) })()  function noise(lc_context0) {   var li_len = vbuffer.length - 1;   while( li_len -- ) vbuffer[li_len] = Math.random() < 0.5 ? 0 : -1>>0;   lc_context0.putImageData(canvas_data, 0, 0); }  </script>  </html>       


Uint8Array 如果改成 Uint32Array 会更酷, 但是在 (linux) GOOGLE CHROME BROWSER 上会失效或者很难看出效果,虽然在 FIREFOX 上很正常。 因此,俺用 Uint8Array 而不是 Uint32Array。




Uint32Array




其他:

这个有滚屏效果, 动感十足。


       <html>  <head>  </head>     <body>  <canvas id="myCanvas0" width="800" height="600"></canvas>  </body>   <script>   var canvas = null; var context = null; var time = 0; var intervalId = 0;  var makeNoise = function() {   var imgd = context.createImageData(canvas.width, canvas.height);   var pix = imgd.data;    for (var i = 0, n = pix.length; i < n; i += 4) {       var c = 7 + Math.sin(i/50000 + time/7); // A sine wave of the form sin(ax + bt)       pix[i] = pix[i+1] = pix[i+2] = 40 * Math.random() * c; // Set a random gray       pix[i+3] = 255; // 100% opaque   }    context.putImageData(imgd, 0, 0);   time = (time + 1) % canvas.height; }  var setup = function() {   canvas = document.getElementById("myCanvas0");   context = canvas.getContext("2d"); }  setup(); intervalId = setInterval(makeNoise, 50);  </script>  </html>      




【未完待续】



/////////////////////////////////////////////////

俺知乎阅读总量只有 9000万,没跨出一小步 (n<1亿)。盐值低迷(3年了还900+)希望长点盐值。俺的回答您当笑话看看就算了, 别太当真, 不然会被贴吧网友耻笑。


“老麦, 大家都说你是笑话、论坛孤儿和神棍。”

“没错。 只有万分之0.5的读者赞同俺的观点。”

user avatar

即使普通家用计算机也是可以生成真随机数的,只不过一般情况下没必要用罢了。

随机性从低到高:

  • 一般编程语言的库函数使用伪随机数算法,比如C中的rand()。这种随机数你只要知道初始值和算法,就能迭代出来,是伪随机数。
  • 类Unix系统中有两个虚拟随机硬件/dev/random和/dev/urandom。Linux的/dev/random和/dev/urandom生成的随机数依赖操作系统中的硬件噪声,比如网络数据、鼠标位置、键盘输入等,这些信息不可预测,可以认为是真随机数(当然你要是能记录下计算机系统内每时每刻的全部状态还是能确定这个数的)。区别在于读取时如果熵池不够大,会不会阻塞等待采集噪声,urandom因为不阻塞所以可能熵池不大,随机性不够。FreeBSD的/dev/random和/dev/urandom就只是一个简单的伪随机数发生器,靠Yarrow算法实现。
  • Intel在Ivy Bridge架构之后的处理器支持RDRAND指令,该指令会根据CPU的热噪声和时间中断做为种子生成随机数。根据我们现有的物理学,这个种子根本无法确定,生成的是真真正正的随机数。
user avatar

哎。。。linux生成随机数有一个非常简单的方法。

获取一个外设的中断计时。

计算机作为一种可预测性较强的设备,很难生成真正的随机数,然而可以使用伪随机数算法来缓解这个问题。但伪随机数有很致命的一点,就是攻击者可以通过各种攻击手段猜到伪随机数发生器的序列,在一些应用场景下,使用这样的伪随机数是十分危险的。
为了解决上面的问题,我们可以从计算机的环境中收集“环境噪音”等外部攻击者难以获取的信息,然后把它们用于随机数的生成,就可以确保产生的随机数难以被预测。来自环境的随机性来源包括键盘、鼠标和某些中断的中断计时,以及其他非确定性特别强和难以被预测的事件。把这些来源的随机性使用类似CRC机制的方法加入到“熵池”中,这种CRC机制在密码学角度可能不是特别安全,但速度足够快,也可以在一定程度上避免被恶意加入熵。在加入熵的过程中,还会根据实际情况计算随机数产生器的内部状态中的熵值,即该熵值代表该系统的随机程度,侧面反映该系统此刻的安全性。

类似的话题

  • 回答
    这个问题很有意思,也触及了计算机科学中最基础也最核心的原理之一。简单来说,计算机生成的随机数,并不是真正意义上的“随机”。咱们一步步来聊聊这个话题,尽量说得通俗易懂。什么是真正的“随机”?想象一下,你在玩石头剪刀布。你的选择是随机的,对吧?你不会提前想好,也不会有任何规律可循。即使你每次都出“石头”.............
  • 回答
    这倒是一个很有趣的设想,用“宏观”电路来构建一台现代计算机。要回答这个问题,我们得先拆解一下“宏观电路”和“现代计算机”各自的特性,然后才能比较它们在速度上的差异。1. 什么是“宏观电路”?我们现在日常接触到的电子设备,从手机到高性能服务器,里面的核心部件——集成电路(IC)——都是微观甚至纳米级别.............
  • 回答
    你这个问题问得特别好,触及到了计算机科学中最根本的几个层面。你说工程上充满了不确定性,比如元件的细微差异、环境的波动,这些确实是客观存在的。那么为什么我们不能直接利用这些“不确定”来生成“真随机数”,反而要依赖那些“看似随机”的伪随机数呢?这背后其实是计算机的本质和我们对“随机”的定义在起作用。一、.............
  • 回答
    这就像一个数字的“黑洞”,一旦你进入这个过程,无论你最开始输入什么数字,最终都会被吸入一个特定的数值。这个“黑洞”就是我们常说的“不动点”或者“吸引子”。要理解为什么是 0.73 几,我们需要先了解一下 `cos` 函数的性质。`cos` 函数,也就是余弦函数,它的输入是我们熟悉的角度(通常是弧度制.............
  • 回答
    这可真是个有意思的问题,让我想起了小时候老师给我们讲的那些关于线条和形状的知识。在咱们熟悉不过的直角坐标系里,如果要随便画上100个点,它们又不是排成一条直线,那能不能找到一条“万能”的曲线,让这100个点乖乖地待在上面呢?我的第一反应是:不可能。为什么这么说呢?让我慢慢道来。咱们先想想最简单的情况.............
  • 回答
    在 Excel 中,让一个单元格显示另一个单元格中的计算公式,并且当公式中的数值变化时,显示的结果也能随之更新,这其实是一个非常基础但又非常实用的功能。简单来说,你需要在你想要显示公式结果的那个单元格里,输入一个以等号(=)开头的公式,然后引用包含你原始计算式的那一个或多个单元格。我来一步一步拆解给.............
  • 回答
    这是一个非常有趣且核心的宇宙学问题,涉及到我们如何理解宇宙的结构和膨胀。简单来说,不能,我们无法通过测量星系间的相对位置偏移来计算出宇宙的中心位置。 事实上,根据我们目前对宇宙膨胀的理解,宇宙可能根本就没有一个“中心”。让我来详细解释一下原因。宇宙膨胀的本质:不是在向外“爆炸”,而是在“拉伸”理解宇.............
  • 回答
    “破坏计算机信息系统罪”,这词儿听起来挺吓人,但真不是什么事儿都能往里套的。很多人一听到“计算机”、“信息系统”,就觉得好像一碰就碰到了雷区,其实不然。在中国法律里,这罪名可不是万能的“筐”,它有明确的界限和构成要件,不是你想怎么理解就怎么理解的。咱们得先把这个罪名拆开来看,它叫“破坏计算机信息系统.............
  • 回答
    当编程技能不再是稀罕事,甚至成为很多跨界人士的“新爱好”,作为计算机专业出身的我们,优势究竟体现在哪里?这确实是不少同行,包括我自己,会思考的问题。别急,咱们不扯那些虚的“热爱”和“情怀”,就说说实实在在、能让你在人群中脱颖而出的地方,并且保证,我说的是大实话,不带任何AI腔调。首先,得承认,会写代.............
  • 回答
    这则新闻真是让人哭笑不得,也太有“喜感”了吧! 23 场婚礼,这效率,这体力,这钱包,估计得是“空中飞人”加“行走的金库”才能hold住吧。不过话说回来,能收到这么多份子钱,也说明人家朋友多,人缘好,这也不是坏事。至于我的国庆假期嘛,说起来就有点“平凡”了,没有那种轰轰烈烈的婚礼接力赛。我的计划算是.............
  • 回答
    计算机是否可以模拟现实世界的一切,是一个涉及科学、哲学、数学和工程学的复杂问题。以下是对此问题的详细分析: 一、计算机模拟的基本原理计算机模拟的核心是通过数学模型和算法,将现实世界的物理规律、化学反应、生物过程等抽象为可计算的规则,然后在计算机上运行这些规则,从而重现现实中的现象或系统。例如: 天气.............
  • 回答
    作为一名计算机专业的应届本科毕业生,你的薪资范围会受到很多因素的影响,因此无法给出一个绝对精确的数字。但是,我可以为你提供一个详细的薪资分析和影响因素的解读,帮助你更好地理解和预估。一、 大致薪资范围 (一线城市为例,不含年终奖、期权等)首先,要明确一点,不同城市、不同公司、不同岗位、不同技术栈的薪.............
  • 回答
    计算机视觉是否已经进入瓶颈期是一个非常复杂的问题,没有一个简单的“是”或“否”的答案。更准确的说法是,计算机视觉领域正处于一个转型期,在某些方面取得了巨大的进步,但在其他方面,尤其是在实现真正人类水平的理解和泛化能力方面,依然面临着严峻的挑战,可以说是遇到了“瓶颈”或“高原期”。为了详细阐述这个问题.............
  • 回答
    计算机视觉中的目标跟踪是一个至关重要的研究领域,旨在在视频序列中持续地定位和识别一个或多个目标。随着深度学习的兴起,目标跟踪算法取得了显著的进展。以下是一些计算机视觉中经典的目标跟踪算法,我将尽量详细地介绍它们的核心思想、特点和发展历程: 早期经典算法(基于手工特征和滤波)在深度学习普及之前,目标跟.............
  • 回答
    计算机理解图像的过程,是一个将我们人类视觉世界转化为数字信息并进行分析和解释的复杂旅程。它不像人类那样通过眼睛和大脑的生物机制来感知,而是依赖于一系列精密的算法和数学模型。我们可以将其分解为几个关键阶段:第一阶段:图像的数字化(Pixelization) 模拟信号到数字信号的转换: 现实世界的图.............
  • 回答
    “计算机再过几年会没落?” 这是一个非常有趣且具有挑战性的问题。我的回答是:不太可能,但计算机的概念和形式会发生深刻的演变,以至于我们现在理解的“计算机”可能会被超越,甚至被边缘化,但其底层驱动和核心功能将以新的形态继续存在并蓬勃发展。要详细解释这一点,我们需要从几个层面来剖析“计算机的没落”以及“.............
  • 回答
    这个问题很有趣,并且触及了计算机科学教育和职业规划的许多重要方面。简单来说,计算机本科生花大量时间写编译器或操作系统,绝对不是不务正业,反而非常有价值,但也要看具体的学习目标和资源投入。下面我们来详细分析一下:为什么写编译器和操作系统“不是不务正业”?1. 深度理解计算机底层原理的基础: .............
  • 回答
    是的,计算机在德州扑克比赛中不仅可以战胜人类,而且在某些特定情况下,已经能够以压倒性的优势战胜最顶尖的人类玩家。这并非易事,而是多年来人工智能(AI)研究,特别是博弈论和机器学习领域深入探索的成果。为了详细说明这一点,我们可以从以下几个方面来解读:1. 德州扑克本身的复杂性德州扑克之所以成为AI研究.............
  • 回答
    这个问题问得非常好,它涉及到计算机内部处理文本的底层原理和不同编码的优劣势。简单来说,计算机不是“不直接使用 UTF8 进行存储”,而是更准确地说,计算机在内部更倾向于使用一种统一的、能够表示所有字符的抽象表示,然后根据需要将其转换为不同的字节序列表示(编码),而 UTF8 就是最常用的一种字节序列.............
  • 回答
    计算机底层访问显卡是一个相当复杂的过程,涉及到多个层次的协作,从操作系统到显卡驱动,再到显卡硬件本身。下面我将尽量详细地阐述这个过程:核心概念:在深入细节之前,理解几个关键概念非常重要: CPU (中央处理器): 负责执行程序指令,包括计算和数据处理。 GPU (图形处理器): 显卡的核心,.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有