電腦程式的執行邏輯本質上是確定性的:給定相同的輸入與初始狀態,輸出必然相同。這看似與「隨機」背道而馳。但現實開發中,我們確實需要不可預測的數值——用於加密、模擬、遊戲邏輯等場景。解決這一矛盾的關鍵,在於偽隨機數生成器。
C語言標準庫函數 rand() 並非真正隨機,而是透過確定性演算法(如線性同餘法)根據一個初始值——種子——推導出一連串看似無規律的數列。若種子固定,每次執行得到的序列完全一致。為了讓結果「每次不同」,常見做法是用當前時間作為種子:
#include <stdlib.h>
#include <time.h>
srand((unsigned)time(NULL)); // 以秒級時間戳為種子
int r = rand(); // 取得偽隨機數
時間精確到秒甚至毫秒/微秒,人為操作無法精確控制呼叫瞬間,因此種子極難預測,達到「近似隨機」的工程效果。
單純的線性同餘法存在統計缺陷(如低位週期短)。現代 C 庫常採用更高質量的演算法(Mersenne Twister、PCG 等),並對輸出進行雜湊/攪拌,進一步打散規律性。開發者也可自行實作或引入 random、arc4random 等更強介面。
/dev/urandom 或 getrandom()。srand(time(NULL)):若循環極快,時間戳不變,產生大量相同數值。僅在程式啟動時初始化一次。rand() % N 取模:會導致分布不均。推薦用浮點縮放或拒絕採樣法。rand() 具體演算法,不同編譯器結果不同。需可重現時請自帶演算法(如 PCG、Xorshift)。C 語言「隨機函數」的本質是確定性演算法 + 不可預測種子。理解偽隨機機制、正確選擇種子來源與演算法,才能在工程中穩健、安全地使用隨機數。