linux下真正的"伪随机数"
来源:互联网 发布:淘宝怎么搜烟 编辑:程序博客网 时间:2024/04/25 19:55
伪随机数,程序员哪个不知,哪个不晓。在linux下,设置好随机种子,然后调用rand()函数,但你真的知道了解它吗?其实你错了,这个"伪"确实够伪的,骗了很多人,不信,看如下代码:
最简单的办法:种子也用随机数来表示。这,我不说你都知道问题了,本来就是求随机数都没出来,你还整个随机种子,表妹知道肯定说打死我。哎,好在linux给我们提供了“真正的”随机数,在内核中,linux会维护一些偶然出现的数据,并且为用户提供访问接口。之所以称之为真正的随机数,是因为这些数据来源于计算机本身的偶然操作,比如硬盘操作、键盘和鼠标的操作,等等。这些操作比起那些通过固定算法生成的伪随机数来说,当然是更真实一些了,它被叫做“熵”。内核提供的接口是/dev/random和/dev/urandom设备,二者的区别是读取时random肯定会返回一个数,如果没有足够的数据,就会阻塞。而urandom则不会阻塞,但是不保证返回的是合适的数据。下面就针对这两个接口来看看真正的随机数是怎么产生的:
#include <stdio.h>#include <stdlib.h>int main(void) { srand(100); printf("%d\n",rand()); return EXIT_SUCCESS;}你把代码运行10遍,发现啥了?咦,怎么每次的结果都一样啊,这样别人如果知道种子(100)了,就知道结果了,这样的结果配叫随机数啊。常用的方法就是种子用时间来计算,但安全性不高,你我都知道你会用时间做种子算法,那还安全啊,我每次打游戏老怪就老蹲在一个地方打,反正你是"随机坐标"出来的怪兽嘛!显然问题相当严重了,那咋办?
最简单的办法:种子也用随机数来表示。这,我不说你都知道问题了,本来就是求随机数都没出来,你还整个随机种子,表妹知道肯定说打死我。哎,好在linux给我们提供了“真正的”随机数,在内核中,linux会维护一些偶然出现的数据,并且为用户提供访问接口。之所以称之为真正的随机数,是因为这些数据来源于计算机本身的偶然操作,比如硬盘操作、键盘和鼠标的操作,等等。这些操作比起那些通过固定算法生成的伪随机数来说,当然是更真实一些了,它被叫做“熵”。内核提供的接口是/dev/random和/dev/urandom设备,二者的区别是读取时random肯定会返回一个数,如果没有足够的数据,就会阻塞。而urandom则不会阻塞,但是不保证返回的是合适的数据。下面就针对这两个接口来看看真正的随机数是怎么产生的:
一,使用/dev/random接口,代码如下:
#include <stdio.h>#include <sys/time.h>#include <fcntl.h>unsigned int new_rand (){ int fd; unsigned int n = 0; fd = open ("/dev/random", O_RDONLY); if (fd > 0) { read (fd,&n,sizeof (n)); } close (fd); return n;}int main (){ int n, i; //init_random (); srand(new_rand()); n = rand (); printf ("n=%d ",rand()); return 0;}这一种方法够简单明了,通过读取linux中真正的伪随机接口/dev/random来真正的随机产生种子,种子都随机了,结果还不随机啊。但问题明显,我刚说了,读取时random肯定会返回一个数,如果没有足够的数据,就会阻塞。这个阻塞有时是会带来安全问题的。
二,使用/dev/urandom接口,代码如下:
#include <stdio.h>#include <sys/time.h>#include <fcntl.h>void init_random (){ unsigned int ticks; struct timeval tv; int fd; gettimeofday (&tv, NULL); ticks = tv.tv_sec + tv.tv_usec; fd = open ("/dev/urandom", O_RDONLY); if (fd > 0) { unsigned int r; int i; for (i = 0; i < 512; i++) { read (fd, &r, sizeof (r)); ticks += r; } close (fd); } srand (ticks);} int main (){ int n, i; init_random (); n = rand (); printf ("n=%d ", n); return 0;}这个方法相比较第一种而言,很明显获取随机种子时麻烦一些,表现在居然循环了512次,遮掩做主要是因为刚说过读取/dev/urandom设备会立即返回,但并不保证会得到合适的数,所以多做几次,保证能获得需要的数。
- linux下真正的"伪随机数"
- linux下的随机数
- 生成真正的随机数!
- 真正的随机数
- 真正的随机数
- 真正的随机数
- 产生真正的随机数
- Random产生重复伪随机数的真正原因 并非时间问题
- 伪随机数的生成
- 伪随机数的生成
- 伪随机数的安全
- 关于linux下的随机数
- 关于linux下的随机数
- 关于linux下的随机数
- 关于linux下的随机数
- linux下的随机数问题
- linux shell伪随机数的产生和应用
- VC生成真正的随机数
- Hive使用注意事项(持续更新)
- 把桌面qt代码编译运行到qpe上的一个例子
- VC选项卡控件的使用方法
- Java初始化顺序
- 常用Js代码汇总
- linux下真正的"伪随机数"
- 方言
- android-仿美丽说有滑动效果的导航栏
- 散列表(HashTable)探秘 --中
- 修改Tomcat7的/webapps/ROOT发布路径
- 散列表(HashTable)探秘 --下
- android-仿美丽说具有按下效果的顶部导航栏
- IOS多线程读写Sqlite问题解决
- Android控件Gallery3D效果