我已经开发了一个随机字符串生成器,但它的行为并不像我所希望的那样。我的目标是能够运行两次,并生成两个不同的四字符随机字符串。但是,它只生成一个四个字符的随机字符串两次。

下面是代码和输出示例:

private string RandomString(int size)
{
    StringBuilder builder = new StringBuilder();
    Random random = new Random();
    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();
}

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// create full rand string
string docNum = Rand1 + "-" + Rand2;

...输出如下:UNTE-UNTE ...但它应该看起来像这个UNTE-FWNU

如何确保两个明显随机的字符串?


当前回答

对于随机字符串生成器:

#region CREATE RANDOM STRING WORD
        char[] wrandom = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','R','S','T','U','V','X','W','Y','Z'};
        Random random = new Random();
        string random_string = "";
        int count = 12; //YOU WILL SPECIFY HOW MANY CHARACTER WILL BE GENERATE
        for (int i = 0; i < count; i++ )
        {
            random_string = random_string + wrandom[random.Next(0, 24)].ToString(); 
        }
        MessageBox.Show(random_string);
        #endregion

其他回答

您正在该方法中创建Random实例,这将导致它在快速连续调用时返回相同的值。我会这样做:

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

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// creat full rand string
string docNum = Rand1 + "-" + Rand2;

(修改后的代码版本)

这是因为Random的每个新实例都在快速调用中生成相同的数字。不要一直创建新实例,只需调用next()并在方法之外声明随机类。

字符串生成器的另一个版本。简单,没有花哨的数学和神奇的数字。而是用一些神奇的字符串来指定允许的字符。

更新: 我将generator设置为静态的,因此当多次调用时,它将不会返回相同的字符串。然而,此代码不是线程安全的,并且绝对不是加密安全的。

对于密码生成,应该使用System.Security.Cryptography.RNGCryptoServiceProvider。

private Random _random = new Random(Environment.TickCount);

public string RandomString(int length)
{
    string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
    StringBuilder builder = new StringBuilder(length);

    for (int i = 0; i < length; ++i)
        builder.Append(chars[_random.Next(chars.Length)]);

    return builder.ToString();
}

在方法中实例化Random对象。

Random对象的种子来自系统时钟,这意味着如果您快速连续多次调用方法,它每次都将使用相同的种子,这意味着它将生成相同的随机数序列,这意味着您将得到相同的字符串。

为了解决这个问题,把你的Random实例移到方法本身之外(当你在做的时候,你可以摆脱对Convert和Floor和NextDouble的疯狂调用序列):

private readonly Random _rng = new Random();
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

private string RandomString(int size)
{
    char[] buffer = new char[size];

    for (int i = 0; i < size; i++)
    {
        buffer[i] = _chars[_rng.Next(_chars.Length)];
    }
    return new string(buffer);
}

结合“推送码”的答案和使用随机生成器种子的答案。我需要它来创造一系列伪可读的“单词”。

private int RandomNumber(int min, int max, int seed=0)
{
    Random random = new Random((int)DateTime.Now.Ticks + seed);
    return random.Next(min, max);
}