Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does this method return the same random string each time?

I need to create a block of unique lines to test a different project I am working on.

So I created a simple program to generate a random string of X length.

The issue is that if I call it once, I get a random string, if I call it again (in a for loop for example) I get the same string for the entire execution of the loop.

I have a feeling that it's being cached or something but I didn't know .net did that and I am just confused at this point.

calling code:

    StreamWriter SW = new StreamWriter("c:\\test.txt");
    int x = 100;
    while (x >0)
    {
        SW.WriteLine(RandomString(20));
        x--;
    }

here is the method:

private static string RandomString(int Length)
{
    StringBuilder sb = new StringBuilder();
    Random randomNumber = new Random();

    for (int i = 0; i <= Length; ++i)
    {
        int x = randomNumber.Next(65, 122);
        sb.Append(Convert.ToChar(x));
    }
    return sb.ToString();        
}

and here is the output:

"VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
..................
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB"

So what gives i thought Random.next() would always return a new random number?

like image 596
Crash893 Avatar asked Apr 30 '09 16:04

Crash893


People also ask

How to generate unique random string in Java?

Using randomUUID() UUID is another Java class that can be used to generate a random string. It offers a static randomUUID() method that returns a random alphanumeric string of 32 characters.

How do you generate random strings?

Using the random index number, we have generated the random character from the string alphabet. We then used the StringBuilder class to append all the characters together. If we want to change the random string into lower case, we can use the toLowerCase() method of the String .


2 Answers

You are creating the Random instances too close in time. Each instance is initialised using the system clock, and as the clock haven't changed you get the same sequence of random numbers over and over.

Create a single instance of the Random class and use it over and over.

Use the using keyword so that the StreamWriter is closed and disposed when you are done with it. The code for a loop is easier to recognise if you use the for keyword.

using (StreamWriter SW = new StreamWriter("c:\\test.txt")) {
   Random rnd = new Random();
   for (int x = 100; x > 0; x--) {
      SW.WriteLine(RandomString(rnd, 20));
   }
}

The method takes the Random object as a parameter.

Also, use the length to initialise the StringBuilder with the correct capacity, so that it doesn't have to reallocate during the loop. Use the < operator instead of <= in the loop, otherwise you will create a string that is one character longer than the length parameter specifies.

private static string RandomString(Random rnd, int length) {
   StringBuilder sb = new StringBuilder(length);
   for (int i = 0; i < length; i++) {
      int x = rnd.Next(65, 122);
      sb.Append((char)x);
   }
   return sb.ToString();        
}
like image 86
Guffa Avatar answered Oct 05 '22 23:10

Guffa


See Random constructor description at MSN, this part:

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers.

So either call the Random() constructor only once at the beginning of your program or use the Random(int32) constructor and define a varying seed yourself.

like image 36
schnaader Avatar answered Oct 06 '22 00:10

schnaader