当我们网站上的用户丢失密码并转到丢失密码页面时,我们需要给他一个新的临时密码。我并不介意这有多随机,或者它是否符合所有“所需的”强密码规则,我想做的只是给他们一个他们以后可以更改的密码。

该应用程序是用c#编写的Web应用程序。所以我想刻薄一点,走一条简单的路线,用Guid的一部分。即。

Guid.NewGuid().ToString("d").Substring(1,8)

Suggesstions吗?想法吗?


当前回答

public static string GeneratePassword(int passLength) {
        var chars = "abcdefghijklmnopqrstuvwxyz@#$&ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new string(
            Enumerable.Repeat(chars, passLength)
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());
        return result;
    }

其他回答

灵感来自@kitsu的回答。但使用RandomNumberGenerator而不是Random或RNGCryptoServiceProvider(在。net 6中已弃用),并添加了一些特殊字符。

可选参数,用于排除在使用System.Text.Json.JsonSerializer.Serialize时将转义的字符—例如&,它转义为\u0026—以便您可以保证序列化字符串的长度与密码的长度匹配。

适用于。net Core 3.0及以上版本。

public static class PasswordGenerator
{
    const string lower = "abcdefghijklmnopqrstuvwxyz";
    const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const string number = "1234567890";
    const string special = "!@#$%^&*()[]{},.:`~_-=+"; // excludes problematic characters like ;'"/\
    const string specialJsonSafe = "!@#$%^*()[]{},.:~_-="; // excludes problematic characters like ;'"/\ and &`+

    const int lowerLength = 26; // lower.Length
    const int upperLength = 26; // upper.Length;
    const int numberLength = 10; // number.Length;
    const int specialLength = 23; // special.Length;
    const int specialJsonSafeLength = 20; // specialJsonSafe.Length;

    public static string Generate(int length = 96, bool jsonSafeSpecialCharactersOnly = false)
    {
        Span<char> result = length < 1024 ? stackalloc char[length] : new char[length].AsSpan();

        for (int i = 0; i < length; ++i)
        {
            switch (RandomNumberGenerator.GetInt32(4))
            {
                case 0:
                    result[i] = lower[RandomNumberGenerator.GetInt32(0, lowerLength)];
                    break;
                case 1:
                    result[i] = upper[RandomNumberGenerator.GetInt32(0, upperLength)];
                    break;
                case 2:
                    result[i] = number[RandomNumberGenerator.GetInt32(0, numberLength)];
                    break;
                case 3:
                    if (jsonSafeSpecialCharactersOnly)
                    {
                        result[i] = specialJsonSafe[RandomNumberGenerator.GetInt32(0, specialJsonSafeLength)];
                    }
                    else
                    {
                        result[i] = special[RandomNumberGenerator.GetInt32(0, specialLength)];
                    }
                    break;
            }
        }

        return result.ToString();
    }
}

插入一个定时器:timer1, 2个按钮:button1, button2, 1个textBox: textBox1,和一个comboBox: comboBox1。请务必申报:

int count = 0;

源代码:

 private void button1_Click(object sender, EventArgs e)
    {
    // This clears the textBox, resets the count, and starts the timer
        count = 0;
        textBox1.Clear();
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    // This generates the password, and types it in the textBox
        count += 1;
            string possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
            string psw = "";
            Random rnd = new Random { };
            psw += possible[rnd.Next(possible.Length)];
            textBox1.Text += psw;
            if (count == (comboBox1.SelectedIndex + 1))
            {
                timer1.Stop();
            }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        // This adds password lengths to the comboBox to choose from.
        comboBox1.Items.Add("1");
        comboBox1.Items.Add("2");
        comboBox1.Items.Add("3");
        comboBox1.Items.Add("4");
        comboBox1.Items.Add("5");
        comboBox1.Items.Add("6");
        comboBox1.Items.Add("7");
        comboBox1.Items.Add("8");
        comboBox1.Items.Add("9");
        comboBox1.Items.Add("10");
        comboBox1.Items.Add("11");
        comboBox1.Items.Add("12");
    }
    private void button2_click(object sender, EventArgs e)
    {
        // This encrypts the password
        tochar = textBox1.Text;
        textBox1.Clear();
        char[] carray = tochar.ToCharArray();
        for (int i = 0; i < carray.Length; i++)
        {
            int num = Convert.ToInt32(carray[i]) + 10;
            string cvrt = Convert.ToChar(num).ToString();
            textBox1.Text += cvrt;
        }
    }

我再加上一个不明智的答案。

我有一个用例,我需要机器-机器通信的随机密码,所以我对人类的可读性没有任何要求。我也没有会员资格。GeneratePassword在我的项目,并不想添加依赖。

我相当肯定会员资格。GeneratePassword做的事情与此类似,但是在这里您可以调整要从中绘制的字符池。

public static class PasswordGenerator
{
    private readonly static Random _rand = new Random();

    public static string Generate(int length = 24)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*_-=+";

        // Get cryptographically random sequence of bytes
        var bytes = new byte[length];
        new RNGCryptoServiceProvider().GetBytes(bytes);

        // Build up a string using random bytes and character classes
        var res = new StringBuilder();
        foreach(byte b in bytes)
        {
            // Randomly select a character class for each byte
            switch (_rand.Next(4))
            {
                // In each case use mod to project byte b to the correct range
                case 0:
                    res.Append(lower[b % lower.Count()]);
                    break;
                case 1:
                    res.Append(upper[b % upper.Count()]);
                    break;
                case 2:
                    res.Append(number[b % number.Count()]);
                    break;
                case 3:
                    res.Append(special[b % special.Count()]);
                    break;
            }
        }
        return res.ToString();
    }
}

以及一些示例输出:

PasswordGenerator.Generate(12)
"pzY=64@-ChS$"
"BG0OsyLbYnI_"
"l9#5^2&adj_i"
"#++Ws9d$%O%X"
"IWhdIN-#&O^s"

为了消除对使用Random的抱怨:随机性的主要来源仍然是加密RNG。即使你可以确定地预先确定随机产生的序列(假设它只产生1),你仍然不知道下一个被选中的字符(尽管这会限制可能性的范围)。

一个简单的扩展是为不同的字符集添加权重,这就像提高最大值和添加下降情况来增加权重一样简单。

switch (_rand.Next(6))
{
    // Prefer letters 2:1
    case 0:
    case 1:
        res.Append(lower[b % lower.Count()]);
        break;
    case 2:
    case 3:
        res.Append(upper[b % upper.Count()]);
        break;
    case 4:
        res.Append(number[b % number.Count()]);
        break;
    case 5:
        res.Append(special[b % special.Count()]);
        break;
}

对于一个更人性化的随机密码生成器,我曾经使用EFF骰子字列表实现了一个提示系统。

检查这段代码… 我添加了.remove(长度)来改善anaximander的反应

            public string GeneratePassword(int length)
            {
                using(RNGCryptoServiceProvider cryptRNG = new RNGCryptoServiceProvider();)
               {
                      byte[] tokenBuffer = new byte[length];
                      cryptRNG.GetBytes(tokenBuffer);
                      return Convert.ToBase64String(tokenBuffer).Remove(length);
                }
                          
            }

validChars可以是任何结构,但我决定基于ascii码范围选择删除控制字符。本例中为12个字符的字符串。

string validChars = String.Join("", Enumerable.Range(33, (126 - 33)).Where(i => !(new int[] { 34, 38, 39, 44, 60, 62, 96 }).Contains(i)).Select(i => { return (char)i; }));
string.Join("", Enumerable.Range(1, 12).Select(i => { return validChars[(new Random(Guid.NewGuid().GetHashCode())).Next(0, validChars.Length - 1)]; }))