首先,「真隨機」也有不同的含義,若想要「真正的真隨機」目測只能靠量子力學了。一般的所謂真隨機不是指這個,而是指統計意義上的隨機,也就是具備不確定性,可以被安全的用於金融等領域,下面說的也是這種。
答案是,計算機系統可以產生統計意義上的真隨機數。
大部分程序和語言中的隨機數(比如 C 中的,MATLAB 中的),確實都只是偽隨機。是由可確定的函數(常用線性同余),通過一個種子(常用時鍾),產生的偽隨機數。這意味着:如果知道了種子,或者已經產生的隨機數,都可能獲得接下來隨機數序列的信息(可預測性)。
直觀來想,計算機是一種可確定,可預測的的設備,想通過一行一行的確定的代碼自身產生真隨機,顯然不可能。但是,我們或許可以迂回一下……
實現方法簡單說就是軟硬結合,或者說,引入系統外的變量(把軟件,代碼,算法想象成一個封閉的系統)。
一個典型的例子就是 UNIX 內核中的隨機數發生器(/dev/random),它在理論上能產生真隨機。即這個隨機數的生成,獨立於生成函數,這時我們說這個產生器是非確定的。
具體來講,UNIX 維護了一個熵池,不斷收集非確定性的設備事件,即機器運行環境中產生的硬件噪音來作為種子。
比如說:時鍾,IO 請求的響應時間,特定硬件中斷的時間間隔,鍵盤敲擊速度,鼠標位置變化,甚至周圍的電磁波等等……直觀地說,你每按一次鍵盤,動一下鼠標,鄰居家 wifi 信號強度變化,磁盤寫入速度,等等信號,都可能被用來生成隨機數。
更具體的,內核提供了向熵池填充數據的接口:
比如鼠標的就是
void add_mouse_randomness(__u32 mouse_data)
內核子系統和驅動調用這個函數,把鼠標的位置和中斷間隔時間作為噪音源填充進熵池。
所以,結論是,程序和算法本身不能產生真隨機,但是計算機系統作為整體可以迂回產生統計意義上的真隨機。
參考:
- 內核源碼在/drivers/char/random.c
- Windows 中也有相對的隨機數生成器,基本的思想是一致的
- 如果要求更高的話,也有專用的設備,可收集附近的電磁場等環境噪音來產生隨機數