5

I want to create a program which only needs one random number, so I try to use the address of argc in main function as random source because I think the location of the program in memory is random, and also it can save some include statements, so I tried:

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

but I found the output at each time is not very "random": they are multiples of 4:

17591828907268
17591841542404
17591845040388
17591834556676

What is the reason? And is using address of argc as random number possible?

Then I try remove some bits of the address:

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

it looks quite random this time, at least it has both odd and even numbers:

34359070631
34359034616
34359078055
34359080624

is that "correct" way to turn the address of argc into random number?

ggrr
  • 7,737
  • 5
  • 31
  • 53
  • Are you asking if `&argc` is a good seed to use for `srand()`? – Patrick Roberts Jan 11 '16 at 04:41
  • It's unlikely that the location of the program in memory is random. The OS uses an algorithm to determine where in memory the program is placed and that algorithm reflects some strategy chosen by the OS. – Dko Jan 11 '16 at 05:39
  • There's really no such thing as "one random number". There are random sequences of numbers. If you need only one number for each run of the program, then you must choose it from a sequence generated outside of your program. John Hascall's suggestion of /dev/random is an excellent choice. Something like random.com is another. – Lee Daniel Crocker Jan 19 '16 at 23:41

3 Answers3

3

What is the reason?

Alignment requirements for your architecture, which I assume is x86 and int is 4 bytes, which means each int should be aligned to an address that is divisible by 4 (which is exactly the behavior you're seeing).

And is using address of argc as random number possible?

Possible? Yeah, sure. You just go ahead and do it.

Is it a good idea? No, definitely not. See below for why.

Is that "correct" way to turn the address of argc into random number?

I assume by "correct" you mean a good source of entropy, and the answer to that is no.

There is some degree of address space layout randomization in modern operating systems, but it's not meant to be a good source of entropy. It's just meant to make it harder for someone to use a bug in your program as a security exploit. And there really aren't any guarantees about ASLR (you can turn it off in some operating systems if you really wanted to).

In short, you should not use the address of a variable as your source for entropy. It's just not a good source of randomness.

Cornstalks
  • 37,137
  • 18
  • 79
  • 144
1

If you really need randomness, you should use one of:

  1. /dev/random
  2. /dev/urandom

    For info on these two, see How to use /dev/random or urandom in C?

  3. srand()

    Info on seeding srand() is here: Recommended way to initialize srand?

  4. An external library specifically designed for it.

    Some info here A good random number generator for C

Community
  • 1
  • 1
John Hascall
  • 9,176
  • 6
  • 48
  • 72
0

It's multiples of 4 because function addresses are going to be word-aligned on every platform I know of (I assume this is x86 or x86_64?)

The address of argc may be "random" for some sense of the word, in that you probably won't know what it is, so if you're using this to seed the starting conditions for a game or whatever that would probably work; definitely don't rely on it if you're using this for crypto or anything -- an attacker could do things to influence where argc gets loaded.

That said, your C library comes with perfectly workable rand() and srand() functions which, as a bonus, let you deliberately seed it with a specific value which can be very helpful in debugging; I stick with that whenever I need random numbers, personally.

Bandrami
  • 4,242
  • 1
  • 13
  • 12