首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言 rand() 偽隨機數機制與優質隨機數獲取指南

     編輯:C 語言問答

rand() 本質:線性同餘生成器 (LCG)

標準庫 `rand()` 通常實現為:next = (next * 1103515245 + 12345) % 2^31 (GLIBC) 或類似參數。特點:

  • 確定性:同種子 `srand(seed)` 產生完全相同序列,利於測試復現。
  • 週期短:2^31-1 ≈ 21 億,大規模模擬易耗盡。
  • 統計質量差:低位周期極短 (最低位週期 2),rand() % N 導致分佈不均 (模數偏差)。
  • 非執行緒安全:全域狀態共享。
  • 不可用於密碼學:可預測、狀態可逆推。

正確使用 rand() 的姿勢

#include <stdlib.h>
#include <time.h>
#include <stdint.h>

// 1. 種子只設一次,用高熵源
void init_rand() {
    uint64_t seed = 0;
    FILE *ur = fopen("/dev/urandom", "rb");
    if (ur) { fread(&seed, 1, sizeof(seed), ur); fclose(ur); }
    else { seed = (uint64_t)time(NULL) ^ (uintptr_t)&seed; }
    srand((unsigned)seed);
}

// 2. 均勻分佈 [0, n-1] (拒絕採樣消除模數偏差)
int rand_uniform(int n) {
    if (n <= 0) return 0;
    const int limit = RAND_MAX - (RAND_MAX % n);
    int r;
    do { r = rand(); } while (r >= limit);
    return r % n;
}

// 3. 浮點 [0.0, 1.0)
double rand_double() {
    return (double)rand() / (RAND_MAX + 1.0);
}

現代優質替代方案

方案標準/庫特點適用場景
C11 `` + 自定義 PCG/Xorshift自實現 / PCG無狀態、執行緒局部、統計質量優、速度極快、種子 128 位高效能模擬、遊戲、非密碼學
C++11 ``STL引擎 (mt19937) + 分佈 (uniform_int_distribution) 分離、型別安全C++ 專案首選
POSIX `random()` / `drand48()`BSD/System V比 `rand()` 好,但仍非密碼學級舊 Unix 代碼遷移
`getrandom()` / `/dev/urandom` / `CryptGenRandom` / `BCryptGenRandom`OS 內核密碼學級真隨機 (熵池)、慢、阻塞 (getrandom flags 控制)金鑰生成、Nonce、Session ID、密碼重設 Token
硬體指令 `RDRAND` / `RDSEED` (x86) / `RNDR` (ARMv8.5)CPU硬體熵源、極快、需檢查 CF/標誌位高吞吐密碼學隨機

選型建議

  • 單執行緒、非關鍵、簡單測試:`rand()` + 拒絕採樣。
  • 多執行緒、高效能模擬、遊戲:PCG/Xorshift128+ (執行緒局部實例)。
  • C++ 專案:`` `std::mt19937_64` + 分佈物件。
  • 任何安全相關 (Token、Key、Salt、IV、Nonce):OS CSPRNG (`getrandom`/`CryptGenRandom`/`/dev/urandom`)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved