如何生成长度为5的随机字母数字字符串?

25
这是我目前的代码。以下是可能重复的问题:如何生成随机字符的字符串?如何在C#中生成随机的8位字母数字字符串?
    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();
    }

但它只创建一个由5个字符组成的随机字符串。我希望它能创建一个由字符和数字组成的5位字符串。我该如何做?谢谢!


如果数字需要高熵或必须安全,我强烈推荐https://dev59.com/qHM_5IYBdhLWcg3whzjx#1344255,而不是其他答案。 - CodesInChaos
@CodeInChaos:如果输出真的需要安全性,那么你链接的答案是合适的。它使用mod来索引chars数组,因此除非chars.Length恰好是256的除数,否则它将表现出偏差。(它还有你在评论中指出的错误。) - LukeH
对于典型字符集(例如最多64个字符),偏差通常较小,因此在实践中可能并不会构成风险。我懒得编写一个不依赖于我的randomgen库的好解决方案。 - CodesInChaos
3个回答

51

使用输入数组来获取数值:

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

或者(必然的)Linq解决方案:

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

2
我不知道这是否是一个问题,但也许值得指出的是,你的代码会更频繁地选择字母而不是数字。 - Igor Korkhov
没错!我也不知道原始问题中的 Convert.ToChar-Convert.ToInt32-Math.Floor-NextDouble 这个怪物是从哪里来的,但它出现在很多 SO 的问题(和答案)中。 - LukeH
不应该多次初始化您的 Random 实例 - 绝对不要在循环中这样做。 - BrokenGlass
@Adrian Hey - 看起来有人编辑了答案并放入了一个错误 - 我已经更新了。请记住,这需要在 OP 在他的问题中添加的静态 Random 实例 random 被定义。 - BrokenGlass
@HoangMinh,请查看原始帖子,它在那里。 - Anirudha Gupta
显示剩余4条评论

24

从Jon Skeet的答案中得到启示...

https://dev59.com/5kfSa4cB1Zd3GeqPBfJl#976674
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);
}

1
不要复制他的答案,投票将此问题标记为重复,并提供到先前类似问题的链接。 - jason
7
我说过我是从他的答案中复制,而不是直接拿过来。从 OPS 的问题来看,我相信我已经改变了足够多的内容,以便对他有所帮助。 - Ohad Schneider
8
这种方法的速度大约是被标记答案的两倍。对于10m的结果,@BrokenGlass=0.4148740 - @OhadSchneider=0.02963571。 - TheGeekZn

0

替换

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

通过

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

请注意,您的代码不会创建不可预测的随机字符串。特别是只有20亿种可能的结果,如果您的计算机经常重新启动,则其中一些结果比其他结果更有可能。
如果您想要不可预测的随机字符串,您应该使用RNGCryptoServiceProvider。您可以在https://dev59.com/qHM_5IYBdhLWcg3whzjx#1344255找到一个示例,您只需要添加连字符即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接