SylixOS下獲取隨機數方法
1. 概述
隨機數是專門的隨機試驗的結果,數學上產生的隨機數被稱為“偽隨機數”,真正的隨機數是由物理方法產生的。隨機數的產生是由算術規則產生,由於隨機數種子的不同,最終生成的隨機數也不相同。如果隨機數種子相同,則生成的隨機數也是相同的,因此要產生隨機數,隨機數種子必須是隨機的。
在編程過程中,有的時候需要通過代碼生成隨機數,SylixOS提供了生成隨機數的函數以及隨機數設備。
2. 函數介紹
SylixOS提供獲取隨機數種子函數srand,以及rand函數產生隨機數。
srand函數用於設置隨機數種子,函數如下:
#include <SylixOS.h> VOID srand (uint_t uiSeed);
srand函數原型分析:
參數uiSeed表示隨機數種子,通常產生的隨機數種子是隨機的。
rand函數用於產生隨機數,產生的隨機數在“0 - RAND_MAX”之間,SylixOS當前定義RAND_MAX值為2147483647,函數如下:
#include <SylixOS.h> INT rand(VOID);
rand函數原型分析:
函數根據隨機數種子生產隨機數。
3. 獲取隨機數
隨機數的產生與隨機數種子相關,通常獲取隨機數可以通過當前時間獲取和讀取隨機數設備獲取。
3.1 通過系統時間獲取隨機數
通過time函數獲取當前的系統時間,通過當前的系統時間生產隨機數種子。由於系統時間是在不斷的變化,因此保證了每次的隨機種子是不相同的。
示例代碼如程序清單 3-1所示。
程序清單 3-1 通過系統時間獲取隨機數
#include <stdio.h> #include <stdlib.h> #include <time.h> int main (int argc, char **argv) { int i = 0; srand((unsigned int)time(NULL)); /* 生成隨機數種子 */ for (i = 0; i < 10; i++) { printf("%d\n", rand() % 100 +1); /* 生成1-100之間的隨機數 */ } return (0); }
運行程序清單 3-1所示代碼,結果如下:
[[email protected]:/root]# /apps/test_rand/test_rand random : 65 random : 26 random : 84 random : 56 random : 56 random : 92 random : 82 random : 35 random : 83 random : 36 [[email protected]:/root]# /apps/test_rand/test_rand random : 89 random : 81 random : 90 random : 20 random : 16 random : 51 random : 23 random : 47 random : 94 random : 5
運行程序2次,由結果可知兩次的運行結果是不一樣的。
3.2 隨機數設備獲取隨機數
計算機本身是可預測的系統,因此用計算機算法不可能產生真正的隨機數。但是機器的環境中充滿了各種各樣的噪聲,如硬件設備發生中斷的時間,用戶點擊鼠標的時間間隔等是完全隨機的,事先無法預測。
SylixOS內核實現的隨機數發生器正是利用系統中的這些隨機噪聲來產生高質量隨機數序列。SylixOS中的隨機數可以從兩個特殊的文件中產生,一個是“/dev/urandom”,另一個是“/dev/random”。它們產生隨機數的原理是利用當前系統的熵池來計算出固定數量的隨機比特,然後將這些比特作為字節流返回。
熵池就是當前系統的環境噪音,熵指的是一個系統的混亂程度,系統噪音可以通過很多參數來評估,如內存的使用、文件的使用量、不同類型的進程數量等。如果當前環境噪音變化的不是很劇烈或者當前環境噪音很小,比如剛開機的時候,而當前需要大量的隨機比特,這時產生的隨機數的隨機效果相對較差。
“/dev/urandom”文件和“/dev/random”文件不同之處在於後者在不能產生新的隨機數時會阻塞程序,而前者不會(ublock),但是產生的隨機數效果相對不是很好,這對加密解密這樣的應用來說就不是一種很好的選擇。
SylixOS提供“/dev/urandom”和“/dev/random”兩種隨機設備,如圖 3-1所示。
圖 3-1 隨機數設備
利用該設備獲取隨機數,示例代碼如程序清單 3-2所示。
程序清單 3-2 通過隨機數設備獲取隨機數
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int iFd; unsigned int uiSeed; iFd = open("/dev/urandom", O_RDWR); /* 打開隨機數設備文件 */ if (iFd < 0) { sprintf(stderr, "open error\n"); close(iFd); return(-1); } if (read(iFd, &uiSeed, sizeof(uiSeed)) < 0) { /* 讀取隨機數設備 */ sprintf(stderr, "read error\n"); close(iFd); return (-1); } srand(uiSeed); /* 獲取隨機數種子 */ printf("random : %d\n", rand()); /* 獲取隨機數 */ close(iFd); return (0); }
運行程序清單 3-2所示代碼,運行結果如下:
[[email protected]:/root]# /apps/test_rand/test_rand random : 993515266 [[email protected]:/root]# /apps/test_rand/test_rand random : 221898156 [[email protected]:/root]# /apps/test_rand/test_rand random : 1087964684 [[email protected]:/root]# /apps/test_rand/test_rand random : 816671734 [[email protected]:/root]# /apps/test_rand/test_rand random : 2027404039 [[email protected]:/root]# /apps/test_rand/test_rand
運行示例程序5次,由運行結果可知每次產生的隨機數是不同的。
4. 參考資料
《SylixOS應用程序開發手冊》
SylixOS下獲取隨機數方法