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所示代码,结果如下:
[root@sylixos:/root]# /apps/test_rand/test_randrandom : 65random : 26random : 84random : 56random : 56random : 92random : 82random : 35random : 83random : 36[root@sylixos:/root]# /apps/test_rand/test_randrandom : 89random : 81random : 90random : 20random : 16random : 51random : 23random : 47random : 94random : 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 intuiSeed; 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所示代码,运行结果如下:
[root@sylixos:/root]# /apps/test_rand/test_randrandom : 993515266[root@sylixos:/root]# /apps/test_rand/test_randrandom : 221898156[root@sylixos:/root]# /apps/test_rand/test_randrandom : 1087964684[root@sylixos:/root]# /apps/test_rand/test_randrandom : 816671734[root@sylixos:/root]# /apps/test_rand/test_randrandom : 2027404039[root@sylixos:/root]# /apps/test_rand/test_rand
运行示例程序5次,由运行结果可知每次产生的随机数是不同的。
4. 参考资料
《SylixOS应用程序开发手册》