注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

绿色圣光

~生活·自愚自乐~

 
 
 

日志

 
 

我需要一个整型随机数  

2013-03-18 19:36:26|  分类: 个人作品 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

int i_random(void)
{
    int random_num = 0;

    int fd_urandom = open("/dev/urandom", O_RDONLY);
    if (fd_urandom < 0)
    {
        printf("Open /dev/urandom failed !\n");

        char statebuf[256];
        struct random_data randomData;

        memset(&randomData, 0, sizeof(randomData));

        initstate_r(0, statebuf, sizeof(statebuf), &randomData);
        srandom_r(time(NULL), &randomData);
        random_r(&randomData, &random_num);

        return random_num;
    }

    read(fd_urandom, &random_num, sizeof(random_num));

    close(fd_urandom);

    return random_num;
}

时间回到上周末,我的代码里需要一个整型随机数。于是乎,我就想,我该用什么方法好呢?

反正是 Linux 平台,要不,直接读取 Linux 的随机数文件?传说中的真随机数哎!好吧,反正也容易。但是,万一 /dev/urandom 打不开怎么办?混蛋!你是不是想的太多了?嗯,打不开就用调用随机数函数吧,用时间当种子。

首先,很容易想到 rand 系列函数。当然,Linux 平台,还是用 random 吧。可是我的程序是多线程的,虽然用它们通常也不会出什么问题,但又不是没得选,还是别用了吧。既然如此,rand_r 已经被废弃了,就用 random_r ?嘻嘻,还没用过它哎。

作出这个决定以后,我才发现,原来 random_r 不是块软骨头啊!man 手册里的介绍实在是太笼统了,直接调用,貌似是由于 random_data 结构体里会产生野指针,进而导致 Segmentation fault,也就是令人崩溃的“段错误”!直到我下班都没解决……(丢死人了!)好在今早很快就找到解决办法了,原来要先用 initstate_r 初始化,并且之前要把结构体置0。(其实我试了试不置0,也没出现问题)然后,上面那堆垃圾就诞生了。

可是后来,我又一想,32位Linux系统里,整型和长整型不都是4个字节么?如果我直接用 mrand48,呃不,mrand48_r,不是简单多了? drand48_data 结构体里可没指针变量。这样的话,代码就变成了下面这副模样。

int i_random(void)
{
    int random_num = 0;

    int fd_urandom = open("/dev/urandom", O_RDONLY);
    if (fd_urandom < 0)
    {
        printf("Open /dev/urandom failed !\n");

        struct drand48_data buffer;

        srand48_r(time(NULL), &buffer);
        mrand48_r(&buffer, (long int *)&random_num);

        return random_num;
    }

    read(fd_urandom, &random_num, sizeof(random_num));

    close(fd_urandom);

    return random_num;
}

但是万一换个平台,long和int不一样长呢,虽说程序跑起来应该没问题……够了!你还有完没完了?这破代码会有人移植么?考虑移植性的话,从一开始就不要用 /dev/urandom !

呵呵,好吧,我真的想的太多了……

  评论这张
 
阅读(937)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017