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

下面是代码和输出示例:

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

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


当前回答

以下是我对目前公认答案的修改,我认为它更快更短:

private static Random random = new Random();

private string RandomString(int size) {
    StringBuilder builder = new StringBuilder(size);
    for (int i = 0; i < size; i++)
        builder.Append((char)random.Next(0x41, 0x5A));
    return builder.ToString();
}

注意,我没有使用所有的乘法,math。floor(), Convert等。

编辑:随机的。Next(0x41, 0x5A)可以更改为任何范围的Unicode字符。

其他回答

我发现这更有帮助,因为它是一个扩展,它允许您选择代码的源代码。

static string
    numbers = "0123456789",
    letters = "abcdefghijklmnopqrstvwxyz",
    lettersUp = letters.ToUpper(),
    codeAll = numbers + letters + lettersUp;

static Random m_rand = new Random();

public static string GenerateCode(this int size)
{
    return size.GenerateCode(CodeGeneratorType.All);
}

public static string GenerateCode(this int size, CodeGeneratorType type)
{
    string source;

    if (type == CodeGeneratorType.All)
    {
        source = codeAll;
    }
    else
    {
        StringBuilder sourceBuilder = new StringBuilder();
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Numbers)
            sourceBuilder.Append(numbers);
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Letters)
            sourceBuilder.Append(letters);
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.LettersUpperCase)
            sourceBuilder.Append(lettersUp);

        source = sourceBuilder.ToString();
    }

    return size.GenerateCode(source);
}

public static string GenerateCode(this int size, string source)
{
    StringBuilder code = new StringBuilder();
    int maxIndex = source.Length-1;
    for (int i = 0; i < size; i++)
    {

        code.Append(source[Convert.ToInt32(Math.Round(m_rand.NextDouble() * maxIndex))]);
    }

    return code.ToString();
}

public enum CodeGeneratorType { Numbers = 1, Letters = 2, LettersUpperCase = 4, All = 16 };

希望这能有所帮助。

在我的情况下,密码必须包含:

至少有一个小写字母。 至少一个大写字母。 至少有一个小数。 至少一个特殊字符。

这是我的代码:

    private string CreatePassword(int len)
    {
        string[] valid = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890", "!@#$%^&*()_+" };
        RNGCryptoServiceProvider rndGen = new RNGCryptoServiceProvider();

        byte[] random = new byte[len];
        int[] selected = new int[len];

        do
        {
            rndGen.GetNonZeroBytes(random);

            for (int i = 0; i < random.Length; i++)
            {
                selected[i] = random[i] % 4;
            }
        } 
        while(selected.Distinct().Count() != 4);

        rndGen.GetNonZeroBytes(random);

        string res = "";

        for(int i = 0; i<len; i++)
        {
            res += valid[selected[i]][random[i] % valid[selected[i]].Length];
        }
        return res;
    }

在方法中实例化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 static Random random = new Random();

private static string CreateTempPass(int size)
        {
            var pass = new StringBuilder();
            for (var i=0; i < size; i++)
            {
                var binary = random.Next(0,2);
                switch (binary)
                {
                    case 0:
                    var ch = (Convert.ToChar(Convert.ToInt32(Math.Floor(26*random.NextDouble() + 65))));
                        pass.Append(ch);
                        break;
                    case 1:
                        var num = random.Next(1, 10);
                        pass.Append(num);
                        break;
                }
            }
            return pass.ToString();
        }

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

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