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

C 在Nginx中生成均匀分布的随机数?,c,nginx,random,C,Nginx,Random,Nginx似乎有一个名为ngx\u random的内置函数,用于源代码的编译。但它似乎只是被定义为:#define ngx\u random 如果我理解正确,这意味着所有地方Nginx都在调用ngx\u random()它只是在调用(在Linux平台上)。从理论上讲,我不清楚它是否保证在给定范围内以任何方式均匀分布,我怀疑它与rand()类似,并且只有当rangen可被rand\u MAX整除时才是均匀的 但是使用ngx_random的好处是,我相信系统会在启动时自动处理种子。然而,如果我想使用

Nginx似乎有一个名为
ngx\u random
的内置函数,用于源代码的编译。但它似乎只是被定义为:
#define ngx\u random

如果我理解正确,这意味着所有地方Nginx都在调用
ngx\u random()
它只是在调用(在Linux平台上)。从理论上讲,我不清楚它是否保证在给定范围内以任何方式均匀分布,我怀疑它与rand()类似,并且只有当range
n
可被
rand\u MAX
整除时才是均匀的

但是使用ngx_random的好处是,我相信系统会在启动时自动处理种子。然而,如果我想使用一些真正与我的范围一致的东西,比如,我相信在下面的中添加一个新的行

srandom(((无符号)ngx_pid sec^tp->msec);
srand48(((无符号)ngx_pid sec^tp->msec);//已添加,以便我可以使用drand48

<我的假设是关于<代码> NGXYRADION< /COD>正确吗?如果我想在各种模块的任何地方使用<代码> DRAND48 <代码>,以上是唯一的方法吗?

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

代码示例(未测试,未编译,仅用于演示想法)

定义GNU源
#包括
#包括
静态无效(*real_srandom)(uint32_t)=空;
静态void srandom_init(void){
real_srandom=dlsym(RTLD_NEXT,“srandom”);
if(NULL==real\u srandom){
fprintf(stderr,“dlsym”中的错误:%s\n”,dlerror();
}
}
void srandom(uint32_t seed){
if(实随机==NULL){
srandom_init();
}
real_srandom(种子);
srand48(种子);
}
你也可以这样写来替换对random(3)的调用,用你自己的实现来替换它。你唯一不能替换的是RAND_MAX,因为它是以常量编译的


我很高兴听到这个技巧对您是否有效

谢谢!这是一个有趣的想法。不幸的是,我无法在整个nginx映像中替换所有random()或srandom()函数——源代码中的大多数地方都使用random()有理由的是,这不适合我的用例,因为我只需要指定范围的均匀分布。除了在ngx_posix_init.c中显式地为srand48添加种子,然后使用drand48()之外,它看起来并没有太多可用的解决方法当我需要的时候…@Superziyi好吧,你可以像我展示的那样将它们链接起来。链接可能是最安全的选择,因为它保证你不会错过任何srandom()调用。无论如何,好卢卡,我现在明白你的意思了…非常感谢,我会尝试一下!
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
#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);
}