26

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!

3
  • I strongly recommend stackoverflow.com/a/1344255/445517 over other answers, if the number needs high entropy or must be secure. Commented Apr 3, 2012 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.) Commented Apr 3, 2012 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. Commented Apr 3, 2012 at 16:53

3 Answers 3

54

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());
}
Sign up to request clarification or add additional context in comments.

9 Comments

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.
+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).
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();
You should not initialize your Random instance more than once - definitely do NOT do it as part of the loop
it's not compiling. check
|
25

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

3 Comments

Instead of copying his answer, vote to close this question as a duplicate and provide a link to the previous incarnation.
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.
+1 This method is about twice as fast as the marked answer. For 10m results, @BrokenGlass=0.4148740 - @OhadSchneider=0.02963571
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.