Random String Generator Returning Same String

Random String Generator Returning Same String

You're making the Random instance in the method, which causes it to return the same values when called in quick succession. I would do something like this:

private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
private string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}

return builder.ToString();
}

// get 1st random string
string Rand1 = RandomString(4);

// get 2nd random string
string Rand2 = RandomString(4);

// creat full rand string
string docNum = Rand1 + "-" + Rand2;

(modified version of your code)

Random string generator in c++ returns the same value in loops

As the commenters pointed out, srand() sets up the random number generator, and seeds it with it's initial value. As such, it should only be used once per program, befor any uses of rand().

In this case, the call to srand() should be taken out of randomString() and put somewhere before the first call to rand(), probably in main().

Generating random string (for unique code) keeps returning the same random string

You should not call the function, since then the default will take the result of the funcation call.

You thus construct a function:

from django.utils.crypto import get_random_string

CODE_LENGTH = 7

def generate_id_length():
return get_random_string(CODE_LENGTH)

class Test(models.Model):
code = models.CharField(
max_length=CODE_LENGTH,
editable=False,
# no parenthesis ↓
default=generate_id_length
)

if you do not want to move CODE_LENGTH outside the Test class, you can use:

from django.utils.crypto import get_random_string

def generate_id_length():
return get_random_string(Test.code_length)

class Test(models.Model):
code_length = 7
code = models.CharField(
max_length=CODE_LENGTH,
editable=False,
# no parenthesis ↓
default=generate_id_length
)

My 'randomString' function keeps returning the same result

math.random generates a sequence of pseudorandom numbers, that is a deterministic sequence that will resemble an actual random sequence. The sequence generated by math.random will be always the same, unless you use math.randomseed.

For every possible value with which you call math.randomseed, math.random will generate a different pseudorandom sequence.

Try this, for example, and you will see a different sequence:

math.randomseed( 7654321 )
for i = 0, 100 do
print(randomString.generate(16))
end

If you want a truly random sequence you should feed randomseed with a true random number before starting the generation.

Creating a random string results in just duplicate strings c++


for (int i = dis(gen) ; count != 13; count++){

The first time your code calls this function, this for loop will count this up until this count reaches 13. This is fairly simple, and basic.

But you will be surprised to learn that the second time your code calls this function, count is still what it was last time: 13. Why should it be anything else? After all, nothing in the code changed it, between the first and the second call to this function. So this for loop does absolutely nothing, whatsoever. count is already 13.

Furthermore, the first time this function was called, the random letters get accumulated in word. Guess what? This word is still exactly the same. After all, nothing changed word or cleared it.

So this function doesn't do anything the 2nd time it gets called, and it simply returns the same word. And it does the same thing every time it's called. That's why you always get the same string, every time.

What you need to do is remember The Golden Rule Of Computer Programming: "your computer always does exactly what you tell it to do instead of what you want it to do". If you would like your computer to always start counting here with 0, and put the randomly-generated letters into a new word, every time this function is called: then this is exactly what you need to tell your computer to do. The simplest solution is to simply declare count and word as local to this function, and explicitly initialize count to 0 (instead of having them as global variables). It is a pretty popular rule of thumb in C++: the more global variables there are, the more opportunities for bugs exist.

Oh, and the shown code needs to call srand exactly once. It may or may not do anything, in the shown code, but repeatedly calling srand only makes things worse, and not better.

Random string generating same values in different iterations of loop

Define your variable as:

 Static objRandom As System.Random = New System.Random()

as in the answer Random integer in VB.NET

Random String Generator creates same string on multiple calls

The reason for this is that when you construct an instance of the Random class, it seeds itself from the clock, but the accuracy of this clock is not good enough to produce a new seed on every call, if you call it in rapid succession.

In other words, this:

Random r = new Random();
int i = r.Next(1000);
r = new Random();
int j = r.Next(1000);

has a very high probability of producing the same values in i and j.

What you need to do is to:

  • Create and cache the Random instance, so that it is the same instance used for every call (but unfortunately the class isn't thread-safe, so at least keep a cached copy per thread)
  • Seed it with something that changes for each call (which is quite a bit harder, because seeding it with a sequential value will product predictable random numbers)

Here's a sample program that creates a separate Random instance per thread, and seeds those instances from a global random-object. Again, this might produce predictable sequences.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SO2755146
{
public class Program
{
public static void Main()
{
List<Task> tasks = new List<Task>();
for (int index = 0; index < 1000; index++)
tasks.Add(Task.Factory.StartNew(() => Console.Out.WriteLine(RNG.Instance.Next(1000))));
Task.WaitAll(tasks.ToArray());
}
}

public static class RNG
{
private static Random _GlobalSeed = new Random();
private static object _GlobalSeedLock = new object();

[ThreadStatic]
private static Random _Instance;

public static Random Instance
{
get
{
if (_Instance == null)
{
lock (_GlobalSeedLock)
{
_Instance = new Random(_GlobalSeed.Next());
}
}
return _Instance;
}
}
}
}

If you just want to seed each random instance from the clock, but at least produce random sequences per thread, you can simplify it like this:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SO2755146
{
public class Program
{
public static void Main()
{
List<Task> tasks = new List<Task>();
for (int index = 0; index < 1000; index++)
tasks.Add(Task.Factory.StartNew(() => Console.Out.WriteLine(RNG.Instance.Next(1000))));
Task.WaitAll(tasks.ToArray());
}
}

public static class RNG
{
[ThreadStatic]
private static Random _Instance;

public static Random Instance
{
get
{
if (_Instance == null)
_Instance = new Random();

return _Instance;
}
}
}
}

This might make two threads started very close to each other to be seeded with the same value, so there's a tradeoff.

Why does this random string generator always return the same values

Random number generators are in fact not fully random: given the same seed value, multiple instances will generate the same random sequence.

Couldn't say it better than the MSDN documentation for the Random constructor

"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. This problem can be avoided by using
a single Random object to generate all random numbers. You can also
work around it by modifying the seed value returned by the system
clock and then explicitly providing this new seed value to the
Random(Int32) constructor. For more information, see the Random(Int32)
constructor."

So, in your case you need to keep the Random instance as a class-level field or a function parameter, and instantiate it only once.

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

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();
}


Related Topics



Leave a reply



Submit