✅Java中的随机是真随机吗?

典型回答

随机数在计算机应用中使用的比较广泛,最为熟知的便是在通信安全和现代密码学等领域中的应用。

随机数分为真随机数和伪随机数,我们程序中使用的基本都是伪随机数。

  • 真随机数,通过物理实验得出,比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等。需要满足随机性、不可预测性、不可重现性。
  • 伪随机数,通过一定算法和种子得出。软件实现的是伪随机数。

只要这个随机数是由确定算法生成的,那就是伪随机。只能通过不断算法优化,使你的随机数更接近随机。

有限状态机不能产生真正的随机数的。所以,现代计算机中,无法通过一个纯算法来生成真正的随机数。无论是哪种语言,单纯的算法生成的数字都是伪随机数,都是由可确定的函数通过一个种子,产生的伪随机数。


扩展知识

真随机

真正的随机数是使用物理现象产生而不是计算机程序产生的。生成随机数的设备我们称之为真随机数生成器。

这样的设备通常是基于一些能生成低等级、统计学随机的“噪声”信号的微观现象,如热力学噪声、光电效应和量子现象。

从某种程度上来说,基于经典热噪声的随机数芯片读取当前物理环境中的噪声,并据此获得随机数。这类装置相对于基于软件算法的实现,由于环境中的变量更多,因此更难预测。

然而在牛顿力学的框架下,即使影响随机数产生的变量非常多,但在每个变量的初始状态确定后,整个系统的运行状态及输出在原理上是可以预测的,因此这一类装置也是基于确定性的过程,只是某种更难预测的伪随机数(pseudo random number)。

量子力学的发现从根本上改变了这一局面,因为其基本物理过程具有经典物理中所不具有的内禀随机性,从而可以制造出真正的随机数(true random number)产生器。

据美国国家标准与技术研究院(NIST)官网消息,该机构研究人员在2018年4月出版的《自然》杂志上撰文指出(原文地址:https://www.nature.com/articles/s41586-018-0019-0.epdf ),他们开发出一种新方法,可生成由量子力学保证的随机数字。新技术超越了此前获得随机数字的所有方法,得到了“真正的随机数字”,有助增强密码系统的安全性。

NIST数学家彼特·比尔霍斯特进一步解释说:“诸如翻转硬币之类的情况似乎是随机的,但如果能看到硬币确切的下落路径,最终结果也是可以预测的。因此,很难保证给定经典来源真正不可预测。量子力学在产生随机性方面表现更好,量子随机是真正的随机,因为对处于‘叠加’状态的量子粒子进行测量,得到的结果基本上是不可预测的。”

强随机数发生器

强随机数发生器依赖于操作系统底层提供的随机事件。强随机数生成器的初始化速度和生成速度都较慢,而且由于需要一定的熵累积才能生成足够强度的随机数,所以可能会造成阻塞。熵累积通常来源于多个随机事件源,如敲击键盘的时间间隔,移动鼠标的距离与间隔,特定中断的时间间隔等。所以,只有在需要生成加密性强的随机数据的时候才用它。

Java提供的强随机数发生器是java.security.SecureRandom类,该类也是一个线程安全类,使用synchronize方法保证线程安全,但jdk并没有做出承诺在将来改变SecureRandom的线程安全性。因此,同Random一样,在高并发的多线程环境中可能会有性能问题。

原文: https://www.yuque.com/hollis666/xkm7k3/wcye6m29t8dgy5fe