随机文件与随机函数

1. /dev/random/dev/urandom 特殊文件

有些系统会提供两种随机伪设备 :/dev/random /dev/urandom

这两个设备的差别,在 /dev/random 会一直封锁,直到系统所产生的随机数已充分够用,所以它可以确保高品质的随机数。相对地, /dev/urandom 不会死锁,其数据的随机程度也不高。

读取 1KB 的随机码元组

[root@local~]# time dd count=1 bs=1024 if=/dev/random>/dev/null

0+1 records in

0+1 records out

o.ooou 0.020s 0:04.62 0.4% 0+0k 0+0io 86pf+0w

读取 1MB 的随机码元组

[root@local~]# time dd count=1024 bs=1024 if=/dev/urandom>/dev/null

1024+0 records in

2048+0 records out

0.000u 0 0.660s 0:0 0.66 100% 0+0k 0+0io 86pf+Ow

/dev/random 被读取的越多,它的响应越慢。我们用这两个设备在几个系统上实验,发现要自 /dev/random 提取 l0MB 的数据,竟耗掉一天或一天以上。而 /dev/urandom 在我们最快的系统上执行,三秒钟即可产生相同的数据。

这两个伪设备都可以取代 mktemp ,成为产生难以推侧的临时性文件名的替代方案 :

[root@local~]# TMPFILE=/tmp/secret.$(cat /dev/urandom | od –x | tr –d ’ ’| head -n 1)

[root@local~]# echo  $ TMPFILE   # 显示随机文件名

/tmp/secret .00000003024d462705664c043c04410e570492e

此处,我们从 /dev/urandom 读取二进制字节数据流,以 od 将其转换为十六进制,使用 tr 去掉空格,之后在满一行时停止。因为 od 将每个输出行转换为 16' 字节,因而提供了 16 X 8=128 个随机位。

2. 使用随机文件或随机函数产生随机数

typedef struct { uint32_t uuid[4]; //128位随机数 }uuid_t; uint32_t get_random_bytes(uint32_t *p) { int32_t rfd = 0; uint32_t ret = 0; ssize_t len = 0; rfd = open("/dev/urandom", O_RDONLY); if(rfd < 0) { ret = -1; goto out; } len = read(rfd, p ,16UL); //读16个字节 if(16 != len) { ret = -1; } close(rfd); out: return ret; } uint32_t uid_generate_random(uuid_t * new_uuid) { uint32_t *p = NULL; uint32_t ret = 0; memset(new_uuid, 0, sizeof(uuid_t)); p = new_uuid->uuid; ret = get_random_bytes(p); if (0 != ret) { //随机种子 srandom((uint32_t)time(0)^getpid()); *p = (uint32_t)random(); *(p + 1) = (uint32_t)random(); *(p + 2) = (uint32_t)random(); *(p + 3) = (uint32_t)random(); } return ret; }

 

你可能感兴趣的:(c,struct,IO,null,Random)