在Nginx中生成均匀分布的随机数?

时间:2017-09-01 23:23:27

标签: c nginx random

Nginx似乎有一个名为ngx_random的内置函数,它在源代码的various places中使用。但它似乎只被定义为:#define ngx_random random

如果我正确地理解了这一点,那就意味着Nginx正在调用ngx_random()所有的地方(在Linux平台上)random()。从doc我不清楚它是否保证以任何方式给定范围的均匀分布,我怀疑它与rand()类似,它是not uniform at all,并且只会如果范围n可被RAND_MAX整除,则统一。

但使用ngx_random的好处是我相信系统会在启动时自动处理播种。然而,如果我想在我的范围内使用真正统一的内容,例如drand48,我相信必须在ngx_posix_init.c之后添加以下新内容?

srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
srand48(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec); //Added so that I can use drand48

我对ngx_random的假设是正确的吗?如果我想在各个模块的任何地方使用drand48,上面是唯一的方法吗?

1 个答案:

答案 0 :(得分:1)

我从未尝试过使用nginx,所以请考虑一下这个想法。在Linux(或类似的基于ELF的系统,例如Solaris)上,您可以使用LD_LIBRARY_PRELOAD技巧替换和/或拦截标准C库中的弱符号。它通常用于拦截和/或替换malloc,但也可能适用于您

代码示例(未经测试,未编译,仅用于演示创意)

#define _GNU_SOURCE

#include <stdlib.h>
#include <dlfcn.h>

static void (*real_srandom)(uint32_t) = NULL;

static void srandom_init(void) {
    real_srandom = dlsym(RTLD_NEXT, "srandom");
    if (NULL == real_srandom) {
        fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
    }
}

void srandom(uint32_t seed) {
    if(real_srandom == NULL) {
        srandom_init();
    }

    real_srandom(seed);
    srand48(seed);
}

您可以编写SO来替换对random(3)的调用,将其替换为您自己的实现。唯一不能替代的是RAND_MAX,因为它是以常量编译的。

我很高兴听到这个技巧对你有用吗<​​/ p>