21

Possible Duplicate:
Is this a good way to generate a string of random characters?
How can I generate random 8 character, alphanumeric strings in C#?

This is the code that I have so far.

    private void button1_Click(object sender, EventArgs e)
    {
        string rand1 = RandomString(5);
        string rand2 = RandomString(5);
        string rand3 = RandomString(5);
        string rand4 = RandomString(5);
        string rand5 = RandomString(5);
        textBox1.Text = rand1 + "-" + rand2 + "-" + rand3 + "-" + rand4 + "-" + rand5;

    }
    private static Random random = new Random((int)DateTime.Now.Ticks);
    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();
    }

BUT it just creates a random string of 5 chars. I want it to create a string of 5 chars and integers. How would I do this? Thanks in advance!

Community
  • 1
  • 1
Ian Lundberg
  • 1,635
  • 8
  • 27
  • 46
  • I strongly recommend http://stackoverflow.com/a/1344255/445517 over other answers, if the number needs high entropy or must be secure. – CodesInChaos Apr 03 '12 at 15:12
  • @CodeInChaos: If the output *really* needs to be secure then the answer you've linked to is *not* suitable. It uses mod to index into the `chars` array so it'll exhibit bias unless `chars.Length` happens to be a divisor of 256. (It also has the bug that you call out in your comment there.) – LukeH Apr 03 '12 at 16:32
  • @LukeH For typical character sets (say up to 64 chars) the bias will be relatively small, and thus probably isn't a risk in practice. I'm too lazy to write a good solution that doesn't depend on my randomgen library. – CodesInChaos Apr 03 '12 at 16:53

3 Answers3

47

Use an input array to draw your values from:

private static string RandomString(int length)
{
    const string pool = "abcdefghijklmnopqrstuvwxyz0123456789";
    var builder = new StringBuilder();

    for (var i = 0; i < length; i++)
    {
        var c = pool[random.Next(0, pool.Length)];
        builder.Append(c);
    }

    return builder.ToString();
}

Or the (inevitable) Linq solution:

private static string RandomString(int length)
{
    const string pool = "abcdefghijklmnopqrstuvwxyz0123456789";
    var chars = Enumerable.Range(0, length)
        .Select(x => pool[random.Next(0, pool.Length)]);
    return new string(chars.ToArray());
}
BrokenGlass
  • 149,257
  • 27
  • 271
  • 318
  • 2
    I don't know if it's a problem or not, but maybe it's worth pointing out that your code will pick letters more often than digits. – Igor Korkhov Apr 03 '12 at 15:00
  • +1, Exactly! I've no idea where the OP's `Convert.ToChar`-`Convert.ToInt32`-`Math.Floor`-`NextDouble` monstrosity came from originally, but it turns up in loads of SO questions (and answers, unfortunately). – LukeH Apr 03 '12 at 15:02
  • Not sure why this works for everyone else but not me. When i call the RandomString method, I get identical digits, 16 of them to be precise. From experience, calling Random.Next within a loop, or via Lambda expression/loops - calls the Random.Next so rapidly, that it gets the same seed each time. For a truly random seed, you should feed in Guid.NewGuid().GetHashCode() into the constructor for your Random(); – Baaleos Mar 30 '17 at 16:00
  • You should not initialize your `Random` instance more than once - definitely do NOT do it as part of the loop – BrokenGlass Mar 31 '17 at 16:28
  • it's not compiling. check – Anirudha Gupta Mar 26 '18 at 11:41
  • @Adrian Hey - looks like someone edited the answer and put in an error - I updated. Keep in mind that this needs the static `Random` instance `random` defined that OP added in his question – BrokenGlass Mar 26 '18 at 20:54
  • @BrokenGlass yes, I check the code and change it but forget to see it in history to update it. No worry, it's working now. – Anirudha Gupta Mar 27 '18 at 02:13
  • @AnirudhaGupta: no, it's still now working. It's complaining about the "random" variable !!!! – Hoang Minh Apr 06 '20 at 17:42
  • @HoangMinh check the OP, it's there in source. – Anirudha Gupta Apr 07 '20 at 07:21
20

Copying from jon skeet's answer... https://stackoverflow.com/a/976674/67824

Random rand = new Random();

public const string Alphabet = 
"abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

public string GenerateString(int size)
{
    char[] chars = new char[size];
    for (int i=0; i < size; i++)
    {
        chars[i] = Alphabet[rand.Next(Alphabet.Length)];
    }
    return new string(chars);
}
Community
  • 1
  • 1
Ohad Schneider
  • 33,142
  • 10
  • 150
  • 190
  • 1
    Instead of copying his answer, vote to close this question as a duplicate and provide a link to the previous incarnation. – jason Apr 03 '12 at 16:56
  • 7
    I said I copied *from* his answer, not his answer as is. Judging from the OPS's question, I believe I've changed it enough to be helpful to him. – Ohad Schneider Apr 04 '12 at 08:12
  • 8
    +1 This method is about twice as fast as the marked answer. For 10m results, @BrokenGlass=0.4148740 - @OhadSchneider=0.02963571 – TheGeekZn Apr 17 '14 at 12:47
0

replace

ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));

by

string chars="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
ch=chars[random.Next(chars.Length)];

Note that your code doesn't create unpredictable random strings. In particular there are only 2 billion possible results, and if your computer gets restarted often, some of them are much more likely than others.

If you want unpredictable random strings, you should use RNGCryptoServiceProvider. You can fine an example at https://stackoverflow.com/a/1344255/445517 , you just need to add the hyphens.

Community
  • 1
  • 1
CodesInChaos
  • 100,017
  • 20
  • 197
  • 251