0

the output for my key generator is the same for each part of the key even though I call GetLetter multiple times which should return different results. Any ideas? Much appreciated.

Output (for example) : B1J2-B1J2-B1J2-B1J2

    private void btn_generate_Click(object sender, EventArgs e) {
        txt_generate.Text = Generate();
    }

    public string Generate() {

        string[] code = new string[4];
        Random number = new Random();

        for (int i =0; i < 4; i++) {
             code[i] = GetLetter();
        }


        string code1 = code[0] + "-" + code[1] + "-" + code[2] + "-" + code[3];

        return code1;

    }

    public string GetLetter() {

        Random number = new Random();

        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        string newWord = "";

        for(int i = 0; i < 4; i++) {
            char temp = chars.ElementAt(number.Next(0, 36));

            newWord += temp.ToString();

        }

        return newWord;
    }
}

}

Ralf
  • 143
  • 1
  • 9

3 Answers3

1

When you call Random number = new Random(); new object is created and random is seeded with some value (usually current time).

As soon as your code executes quite fast, you're creating this object 4 times, but every time seed is the same. This is why all chunks are the same.

You can fix it in two ways:

  1. Move number variable initialization outside of the method, make it static property of the class
  2. Generate all 16 chars without random re-init and then split final string into 4 symbol chunks
Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
0

Refactored it a bit for you:

private void btn_generate_Click(object sender, EventArgs e) {
    txt_generate.Text = Generate();
}

private static Random _random = new Random();

public string Generate() 
{
    return string.Join("-", Enumerable.Range(0, 4).Select(i => GetLetter()));
}

public string GetLetter() 
{
    const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    return new string(Enumerable.Range(0, 4).Select(i => chars[_random.Next(chars.Length)]).ToArray());
}
bashis
  • 1,200
  • 1
  • 16
  • 35
0

The issue comes from creating a new Random instance everytime you call GetLetter and in Generate. Instead you should create a static Random in the class such as.

static Random number = new Random();

private void btn_generate_Click(object sender, EventArgs e)
{
    txt_generate.Text = Generate();
}

public string Generate()
{

    string[] code = new string[4];
    for (int i = 0; i < 4; i++)
    {
        code[i] = GetLetter();
    }


    string code1 = code[0] + "-" + code[1] + "-" + code[2] + "-" + code[3];

    return code1;

}

public string GetLetter()
{
    const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    string newWord = "";

    for (int i = 0; i < 4; i++)
    {
        char temp = chars.ElementAt(number.Next(0, 36));

        newWord += temp.ToString();

    }

    return newWord;
}
Nico
  • 12,493
  • 5
  • 42
  • 62
  • Which would be better, to make the Random object a static member of the class or put the Random object into the Generate function and pass it into GetLetter as a parameter? Both work now, just curious if it's bad practice. – Ralf May 18 '17 at 00:05
  • I would use a static object myself as it will be generated from a single seed and then reused for every subsequent call. Therefore if you have multiple requests to the same methods you will have a less likely chance of duplicate results. – Nico May 18 '17 at 00:08