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

C語言實現偽隨機數生成算法:線性同餘法原理、種子機制與標準庫 rand/srand 対比

     編輯:關於C

計算機無法產生真隨機數,僅能通過確定性算法生成偽隨機序列。本文深度解析線性同餘法 (LCG) 核心算法,對比標準庫 rand/srand 實現,並提供可移植的自定義隨機數生成器代碼。

1. 偽隨機數核心原理

遞推公式:X_{n+1} = (a * X_n + c) mod m

  • m:模數(決定周期上限)
  • a:乘數
  • c:增量(c=0 為乘同餘法)
  • X_0:種子

滿足 Hull-Dobell 定理 條件可達到最大周期 m:

  1. c 與 m 互質
  2. a-1 是 m 所有質因子的倍數
  3. 若 m 為 4 的倍數,則 a-1 也是 4 的倍數

2. 經典參數集

名稱mac用途
glibc (ANSI C)2³¹110351524512345Linux rand() 歷史實現
MSVC2³¹2140132531011Windows rand()
Java Random2⁴⁸2521490391711java.util.Random
POSIX drand482⁴⁸0x5DEECE66D0xB高質量雙精度
Numerical Recipes2³²16645251013904223科學計算推薦

3. 自定義 LCG 實現(移植自 curl/libc)

#include 
#include 

// 全局種子狀態
static uint32_t g_rand_seed = 0;

// 核心生成:返回 32 位隨機數
uint32_t my_rand(void) {
    // 參數同 glibc: a=1103515245, c=12345, m=2^31
    // 此處用 32 位無符號自然溢出實現 mod 2^32,再取高 16 位混合
    g_rand_seed = g_rand_seed * 1103515245u + 12345u;
    // 經典混淆:高低 16 位交換,提升低位隨機性
    return (g_rand_seed << 16) | ((g_rand_seed >> 16) & 0xFFFF);
}

// 種子初始化:使用時間 + 多次預熱
void my_srand(void) {
    g_rand_seed = (uint32_t)time(NULL);
    my_rand(); my_rand(); my_rand();  // 預熱:丟棄前幾個數
}

// 獲取 [0, max) 範圍隨機數
uint32_t my_rand_range(uint32_t max) {
    return my_rand() % max;  // 簡單取模,有輕微統計偏差,工程可用拒絕採樣優化
}

int main() {
    my_srand();
    printf("10 個 0-99 隨機數:\n");
    for (int i = 0; i < 10; i++) {
        printf("%u ", my_rand_range(100));
    }
    printf("\n");
    return 0;
}

4. 標準庫 rand/srand 對比

#include 
#include 

int main() {
    srand((unsigned)time(NULL));  // 種子
    for (int i = 0; i < 10; i++) {
        printf("%d ", rand() % 100);  // RAND_MAX 通常 32767 或 2^31-1
    }
    printf("\n");
    return 0;
}

關鍵差異

特性自定義 LCG標準 rand()
可移植性完全可控,跨平台行為一致實現定義,不同平台序列不同
線程安全全局狀態,非線程安全全局狀態,非線程安全 (C11 有 rand_r)
隨機質量可選高質量參數集通常較差 (LCG 低位周期短)
加密安全否否

5. 現代 C 應用建議

  • 一般用途:C11 rand_r(&seed) 線程安全版,或自定義 LCG/xorshift。
  • 高質量非加密:xorshift64*、PCG、SplitMix64(無狀態、極快、統計優)。
  • 加密安全:/dev/urandom (Linux)、BCryptGenRandom (Windows)、getrandom() (Linux 3.17+)、arc4random() (BSD)。
  • C++11+:std::mt19937 (梅森旋轉) + std::uniform_int_distribution,標準庫首選。

6. xorshift64* 參考實現(推薦替代 LCG)

static uint64_t g_xorshift_state = 1;

uint64_t xorshift64star(void) {
    uint64_t x = g_xorshift_state;
    x ^= x >> 12;
    x ^= x << 25;
    x ^= x >> 27;
    g_xorshift_state = x;
    return x * 0x2545F4914F6CDD1Dull;  // 乘法混淆輸出
}

void xorshift_seed(uint64_t seed) {
    g_xorshift_state = seed ? seed : 1;  // 狀態不能為 0
}

理解偽隨機數的數學本質、參數選擇權衡、標準庫局限性,是編寫可復現測試、模擬系統、遊戲邏輯、非加密協議的基礎能力。嚴禁在密碼學場景使用 LCG/rand/xorshift,必須使用 CSPRNG。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved