代码之家  ›  专栏  ›  技术社区  ›  ggrr

我可以使用argc在main中的地址作为随机源吗?

  •  5
  • ggrr  · 技术社区  · 10 年前

    我想创建一个只需要一个随机数的程序,所以我尝试使用main函数中argc的地址作为随机源,因为我认为程序在内存中的位置是随机的,而且它可以保存一些include语句,所以我试着:

    #include <stdio.h>
    int main(int argc,const char* argv[]){
        printf("%lu\n",(unsigned long int)&argv/sizeof(unsigned long int));
        return 0;
    }
    

    但我发现每次的输出不是很“随机”:它们是4的倍数:

    17591828907268
    17591841542404
    17591845040388
    17591834556676
    

    原因是什么?使用argc的地址作为随机数是可能的吗?

    然后我尝试删除地址的一些部分:

    #include <stdio.h>
    int main(int argc,const char* argv[]){
        printf("%lu\n",(unsigned long int)&argv >> 12);
        return 0;
    }
    

    这次看起来很随机,至少它有奇数和偶数:

    34359070631
    34359034616
    34359078055
    34359080624
    

    将argc的地址转换为随机数是“正确”的方法吗?

    3 回复  |  直到 9 年前
        1
  •  3
  •   Cornstalks    10 年前

    原因是什么?

    Alignment requirements 对于您的体系结构,我假设是x86和 int 是4个字节,这意味着每个 整数 应该与可被4整除的地址对齐(这正是您看到的行为)。

    使用argc的地址作为随机数是可能的吗?

    可能的 Yeah, sure 。你就去做吧。

    这是个好主意吗?不,绝对不是。原因见下文。

    这是将argc的地址转换为随机数的“正确”方法吗?

    我假设你所说的“正确”是指一个好的熵源,而答案是否定的。

    有一定程度的 address space layout randomization 在现代操作系统中,它并不是一个好的熵源。这只是为了让某人更难将程序中的漏洞用作安全漏洞。而且ASLR确实没有任何保证(如果你真的想,可以在某些操作系统中关闭它)。

    简言之,您不应该使用变量的地址作为熵的来源。这不是随机性的好来源。

        2
  •  1
  •   Community Mohan Dere    9 年前

    如果你真的需要随机性,你应该使用以下方法之一:

    1. /开发/随机
    2. /开发(urandom)

      有关这两者的信息,请参见 How to use /dev/random or urandom in C?

    3. srand()

      有关播种srand()的信息如下: Recommended way to initialize srand?

    4. 专门为其设计的外部库。

      此处有一些信息 A good random number generator for C

        3
  •  0
  •   Bandrami    10 年前

    它是4的倍数,因为函数地址将在我所知道的每个平台上进行字对齐(我假设这是x86还是x86_64?)

    argc的地址在某种意义上可能是“随机的”,因为你可能不知道它是什么,所以如果你用它来为一个游戏或其他可能会起作用的游戏设定起始条件;如果您将其用于加密或其他用途,绝对不要依赖它——攻击者可能会影响argc的加载位置。

    也就是说,您的C库附带了完全可行的rand()和srand()函数,作为奖励,您可以故意为其添加一个特定的值,这对调试非常有帮助;无论何时我需要随机数字,我都会坚持这一点。