生成随机字符串

时间:2009-10-15 14:31:13

标签: c# .net

  

可能重复:
  c# random string generator

我需要生成一个给定长度的随机字符串。到目前为止这是我的代码。问题是随机字符串就像“RRRRRR”或“SSSSS”每次都是相同的字母。就在我重新启动应用程序时,字母改变了。我需要像“asrDvgDgREGd”

这样的东西
    public string GenerateChar()
    {
        Random random = new Random();

        return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
    }

    public string GenerateChar(int count)
    {        
        string randomString = "";

        for (int i = 0; i < count; i++)
        {
            nahodneZnaky += GenerateChar();
        }

        return randomString;
    }

11 个答案:

答案 0 :(得分:26)

尝试对整个字符串使用相同的随机对象,而不是为每个字符串初始化一个。

随机对象将基于从“种子”编号开始的数学进展生成“伪随机”数字。如果每次将Random对象初始化为相同的种子,实际上可以获得相同的“随机”数字序列。

现在,当你初始化Random而不指定种子时,它会将计算机的时钟作为种子。在这种情况下,你可能做得足够快,以至于时钟没有从一个初始化改变到另一个初始化,你总能得到相同的种子。

最好在函数中初始化Random对象,生成随机字符串,并将其作为参数传递给GenerateChar函数,这样就可以在Random的同一个实例上多次调用NextDouble()对象,而不是只在其不同的实例上一次。

答案 1 :(得分:19)

您可以省去麻烦并使用Membership.GeneratePassword方法。它基本上是你所需要的。

用法:

int passwordLength = 5;
int alphaNumericalCharsAllowed = 2;
string random = Membership.GeneratePassword(passwordLength, alphaNumericalCharsAllowed);

为了便于阅读,你可以用辅助方法包装它:

private string GenerateRandomString(int length, int alphaNumericalChars)
{
      return Membership.GeneratePassword(length, alphaNumericalChars);
}

答案 2 :(得分:13)

不要在每次迭代时创建Random的新实例 - 这将以当前时间为每个实例播种,以毫秒为单位,这显然不可能在迭代之间发生变化。

创建Random的单个实例,并将其传递给方法。我还建议你不要在循环中连接类似的字符串,甚至创建那么多的字符串。此外,如果您使用Random.Next(int, int)让您的生活更轻松。

试试这个:

public char GenerateChar(Random rng)
{
    // 'Z' + 1 because the range is exclusive
    return (char) (rng.Next('A', 'Z' + 1));
}

public string GenerateString(Random rng, int length)
{ 
    char[] letters = new char[length];
    for (int i = 0; i < length; i++)
    {
        letters[i] = GenerateChar(rng);
    }
    return new string(letters);
}

private static readonly Random SingleRandom = new Random();

public string GenerateStringNotThreadSafe(int length)
{ 
    return GenerateString(SingleRandom, length);
}

现在值得注意的是Random不是线程安全的,所以如果你有多个线程,你不应该在一个静态变量中只有Random的单个实例而不是锁定。有各种各样的方法 - 创建一个Random的子类,其中线程安全的,或者一组静态方法做同样的事情,或者使用线程局部变量来拥有每个帖子一个实例。

我有一个StaticRandom class作为MiscUtil的一部分但是这些天我倾向于线程本地版本并在适当的时候将其传递给链。有一天,我会将其作为MiscUtil的另一个选项...

答案 3 :(得分:9)

没什么特别的,但很短。 32和127是您想要生成的最小和最大字符范围。

public static string GetRandomString(int length)
{
    var r = new Random();
    return new String(Enumerable.Range(0, length).Select(n => (Char)(r.Next(32, 127))).ToArray());
}

答案 4 :(得分:4)

我知道这可能不是最好的解决方案,但我有点像能够指定“允许”字符的想法:

    private const int _defaultNumberOfCharacters = 8;
    private const int _defaultExpireDays = 10;
    private static readonly string _allowedCharacters = "bcdfghjklmnpqrstvxz0123456789";

    public static string GenerateKey(int numberOfCharacters)
    {
        const int from = 0;
        int to = _allowedCharacters.Length;
        Random r = new Random();

        StringBuilder qs = new StringBuilder();
        for (int i = 0; i < numberOfCharacters; i++)
        {
            qs.Append(_allowedCharacters.Substring(r.Next(from, to), 1));
        }
        return qs.ToString();
    }

答案 5 :(得分:1)

也许您可以找到有用的Path.GetRandomFileName方法,具体取决于字符串中您需要的确切字符。

答案 6 :(得分:1)

尝试静态

public string GenerateChar()
{
    static Random random = new Random();

    return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
}

答案 7 :(得分:1)

http://msdn.microsoft.com/en-us/library/system.io.path.getrandomfilename.aspx

string randomName = Path.GetRandomFileName();
randomName = randomName.Replace(".", string.Empty);

// take substring...

答案 8 :(得分:0)

从调用方法传递random并初始化一次 - 您每次都使用相同的种子重新种植Random生成器....

答案 9 :(得分:0)

您应该在方法之外初始化随机变量:

public Random random = new Random();

public string GenerateChar()
    {
       return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
    }

...

答案 10 :(得分:-1)

试试这个。

public string GetRandomString()
{
    int randomNumber = new Random().Next();
    string RandomString = string.Empty;
    for(int i = 0;i < randomNumber.ToString().Length;i++)
    {
        RandomString += ((char)Convert.ToUInt32(randomNumber.ToString()[i])).ToString();
    }
    return RandomString;
}