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