关于linux下的随机数

转载 2012年03月30日 01:16:35
在linux下取随机数,当然可以简单的用rand函数,不过要注意的是一定要设置好种子,否则伪随机数就会变成非常伪的随机数。设置种子,一般就 用time函数返回当前时间即可。一般来讲,这样的做法基本上就可以了,因为虽然我们用的是随机数,但是由于种子不同,从上亿的数中去猜测我们的种子几乎 是不可能的。例如:#include #include #include #define random(x) (rand()%x)

  void main()

  { srand((int)time(0));for(int x=0;x<10;x++)

  printf("%d\n",random(100));}但是如果我们的种子算法被知道了,那么显然就不行了。当然作为某些应用也无所谓,比如我们要在屏幕上随机的画一只小猪。这样的应用几乎不会有谁会去关心下一次会是什么结果。不过有些应用就不一样了,大的不说,就是一些游戏,也得考虑随机数的安全性问题。

  简单的办法是,我们的种子也用随机数来表示。不过这样一来,似乎就有鸡生蛋还是蛋生鸡的问题。好在linux给我们提供了“真正的”随机数,在内核 中,linux会维护一些偶然出现的数据,并且为用户提供访问接口。之所以称之为真正的随机数,是因为这些数据来源于计算机本身的偶然操作,比如硬盘操 作、键盘和鼠标的操作,等等,这些操作比起那些通过固定算法生成的伪随机数来说,当然是更真实一些了,在这里我们有一个很酷的名字叫做“熵”。内核提供的 接口是/dev/random和/dev/urandom设备,二者的区别是读取时random肯定会返回一个数,如果没有足够的数据,就会阻塞。而 urandom则不会阻塞,但是不保证返回的是合适的数据。

  下面的代码中,函数init_random用来生成一个随机的种子,之后直接调rand就可以得到随机数。之所以读了512次,然后全部组合在一起,就是因为urandom设备不保证每一次读到的都是真实的数据。

  另一个函数my_rand则是通过直接去读random设备来得到真实的随机数。这样每一次都是真正的随机数,但是问题在于如果系统的“熵”不够, 那么程序就会阻塞。对于安全性要求比较高的应用来说,可以使用这样的方式。如果“熵”不够,可以人为的去“制造”一些熵。比如下面的程序,如果你不做任何 操作,也许输出几个随机数之后程序就会停止输出,这是你在另一个终端运行一些比较繁忙的进程,比如"find /",就会发现我们的程序又开始源源不断的输出随机数。

  使用random设备的例子很多,比如gpg就会在生成key的时候让你不断的敲键盘直到它满意为止。对于2.4以后的内核,你还可以通过proc 文件系统的接口得到random设备的更多信息,比如 /proc/sys/kernel/random/entropy_avail可以知道系统中还有多少“熵”可以用。运行我们的例子可以发现,这个值一下 子就减少到个位数,直到程序阻塞。另外一个文件也很有意思,那就是/proc/sys/kernel/random/uuid,通过这个接口可以很容易的 得到真正唯一的uuid.关于random设备还有一些可说的,那就是系统安全。有人居然能通过系统启动过程或者系统运行的某段时间产生的熵的内容来破译出某些信息,这听起 来相当高深,不过理论上来讲却完全可能。因为random设备虽然是通过系统噪声来得到熵,但是如果两次系统启动完全一致,那么启动过程中生成的熵当然会 完全一致。不过这些安全漏洞不用我们担心,因为现在的系统都有相关的补丁。

  #include #include #include

  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);printf("init finished ");}

  unsigned int new_rand ()

  { int fd;unsigned int n = 0;fd = open ("/dev/urandom", O_RDONLY);if (fd > 0)

  { read (fd, &n, sizeof (n));} close (fd);return n;}

  int main ()

  { int n, i;init_random ();n = rand ();printf ("n=%d ", n);for(i=0;i<10;i++)

  printf ("%u ", new_rand());}

关于linux下的随机数

在linux下取随机数,当然可以简单的用rand函数,不过要注意的是一定要设置好种子,否则伪随机数就会变成非常伪的随机数。设置种子,一般就用time函数返回当前时间即可。一般来讲,这样的做法基本上就可...
  • x86
  • x86
  • 2008年04月07日 15:24
  • 11680

asp产生随机数

Function gen_key(digits) Create and define array dim char_array(50) char_array(0) = "0" char_array(1...
  • xck01
  • xck01
  • 2006年03月30日 18:08
  • 4645

java生成随机数的代码

package test; /**  * 产生10个随机数的各种方法  * @author Administrator  *  */ public class Test3 {  //利用...
  • xiaohanshenchu
  • xiaohanshenchu
  • 2012年09月28日 17:08
  • 451

C# 产生随机数( DateTime.Now.Ticks)

计算机的“随机数”并非真的“随机数”,而是伪随机数——也就是通过一系列算法,从一个起始数字开始按照一定规则算出来的。 就好像函数F(x)一样,x就是随机数的种子。 你可以做个测试:把你的"new ...
  • liushuo_whu
  • liushuo_whu
  • 2014年08月15日 20:29
  • 905

linux系统产生随机数的6中方法

linux系统产生随机数的6种方法 1、通过系统环境变量($RANDOM)实现 [root@i-1pbhgm8j ~]# echo $RANDOM | md5sum | cut -c 5-11 3ed...
  • m0_37814112
  • m0_37814112
  • 2017年10月09日 15:46
  • 144

自己编写产生随机数函数--MATLAB实现

这学期选了《现代数字信号处理》这门课,全是信号的东东,本科完全没有接触过这个东东,听起来有点费劲,作业还是用matlab做,第一个作业就用到了随机数,本来matlab有自己带的产生随机数的函数,但是老...
  • qust_waiwai
  • qust_waiwai
  • 2013年12月25日 16:31
  • 4505

关于linux上文件路径的问题

使用File.separator解决文件路径跨平台出现的问题
  • Ditto_zhou
  • Ditto_zhou
  • 2017年09月14日 09:33
  • 174

c/cpp中生成随机数

本文由青松原创并依GPL-V2及其后续版本发放,转载请注明出处且应包含本行声明。 from:https://zhidao.baidu.com/question/399826336.html C++中...
  • u011493704
  • u011493704
  • 2016年12月04日 12:17
  • 686

linux下的随机数问题

需求:将字符串通过DES加密
  • jonson123654
  • jonson123654
  • 2014年09月05日 17:49
  • 464

linux下的随机数

在 linux下取随机数,当然可以简单的用rand函数,不过要注意的是一定要设置好种子,否则伪随机数就会变成非常伪的随机数。设置种子,一般就用 time函数返回当前时间即可。一般来讲,这样的做法基本上...
  • eroswang
  • eroswang
  • 2009年07月14日 20:22
  • 1450
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于linux下的随机数
举报原因:
原因补充:

(最多只允许输入30个字)