4

I ran into this problem and I'm so confused.

I am using $RANDOM in bash as a test string at the very beginning of the linux bootup process. Very interestingly, I observed that $RANDOM will be the same every time linux booted up. In my case, it's 18869.

I was simply echoing $RANDOM to a file. I observed the same number in every boot up. After that, $RANDOM seems to return "real" random numbers.

echo "$RANDOM is a test string" >> /tmp/test

Can anyone explain the reason in this?

iglory
  • 101
  • 1
  • 1
  • 4

2 Answers2

5

Here is the initial seed algorithm from variables.c in the Bash 4.2 source code:

static void                                                                                               
seedrand ()                                                                                               
{                                                                                                         
  struct timeval tv;                                                                                      
                                                                                                          
  gettimeofday (&tv, NULL);                                                                               
  sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());                                                            
}  

In other words, it generates the seed based on pid and current time in seconds and microseconds (with a system accuracy of ~1/100th second).

If you check $RANDOM on a small, predictable system, before the system clock is initialized, you're likely to see the same value every time.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Thanks for the information. In this scenario where the system clock is not initialized on an embedded system, what do you suggest to do to generate a random number? – iglory Aug 29 '13 at 21:47
  • Is this embedded system managing /dev/urandom like larger linux distros do? If so, you could ensure your script runs just after /dev/urandom is initialized, and set RANDOM from a few bytes of that data. – sjnarv Aug 29 '13 at 21:57
  • 1
    Some embedded systems like Raspberry Pi has a hardware number generator device you could use. You can also write a file periodically or on shutdown that writes `date +%s >> /tmp/seed` and then `RANDOM=$( – that other guy Aug 29 '13 at 22:29
0

Because the seed is always the same at the startup. You can always assign a value

RANDOM=1000

to seed the RANDOM manually, perhaps with the PID

RANDOM=$$

Trying to find your seed, I wrote this small script

for ((i=-150000; i<150000 ;i=i+1)); do
  RANDOM=$i;
  echo "$i: $RANDOM $RANDOM $RANDOM";
done | grep "18869[^:]"

and found:

-118657: 8608 18869 19673
-108446: 18869 18855 15976
-78471: 694 18869 19296
-75678: 18869 23165 7967
-42910: 18869 27476 32727
-38285: 25548 18869 18919
-10142: 18869 31786 24719
27971: 18869 6258 29786
33149: 13707 18869 8396
60739: 18869 10568 21777
73335: 5793 18869 8019
93507: 18869 14878 13769
113521: 30647 18869 7642
126275: 18869 19188 5761
137004: 18869 3793 18604

See that this script has lots of $RANDOM but still is fully deterministic, it'll result always the same if you call it. This link has more information about $RANDOM and this other link has information on how to use /dev/random and /dev/urandom, as an alternative. Another way to generate a random number without the seed issue is to get some information about the actual time in nanoseconds.

date +%N
H.D.
  • 4,168
  • 1
  • 18
  • 15