设置密码生成器

时间:2018-12-09 16:36:01

标签: c# passwords

我目前正在尝试创建一个随机密码生成器。
如果我只选择一种类型的符号,我的代码就可以正常工作。

将我的代码转换为多种类型的单词的最佳方法是什么?
您还要添加什么参数来使密码更安全?
我正在考虑添加一个if循环来检查一行中是否有两个以上相同的字母,符号或数字。

这就是我的界面的样子:

enter image description here

那是我的代码:

public partial class Form1 : Form
{
    // Max number of identical characters in a row 
    const int Maximum_Identical = 2;
    // lower case chars
    const string lower_chars = "abcdefghijklmnopqrstuvwxyz";
    // capital chars
    const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    // numbers
    const string numbers = "0123456789";
    // symbols
    const string symbols = @"!#$%&*@\";
    // password lenght 
    int lenght;

    private void button1_Click(object sender, EventArgs e)
    {
        //use stringbuilder so I can add more chars later
        StringBuilder password = new StringBuilder();
        //take max lenght from numericUpDown
        lenght = Convert.ToInt32(numericUpDown1.Value);
        // random instance so I can use Next and don't get loops
        Random rdm = new Random();

        if (small_letters__Box.Checked)
        {
            //add a random small character to pass untill it reaches the selected lenght  
            while (lenght-- > 0 )
            {
                password.Append(lower_chars[rdm.Next(lower_chars.Length)]);
            }
        }

        if (capital_letters__Box.Checked)
        {
            //add a random capital character to pass untill it reaches the selected lenght  
            while (lenght-- > 0)
            {
                password.Append(capital_chars[rdm.Next(capital_chars.Length)]);
            }
        }

        if (numbers_Box.Checked)
        {
            //add a random character to pass untill it reaches the selected lenght  
            while (lenght-- > 0)
            {
                password.Append(numbers[rdm.Next(numbers.Length)]);
            }
        }

        if (symbols_Box.Checked)
        {
            //add a random character to pass untill it reaches the selected lenght  
            while (lenght-- > 0)
            {
                password.Append(symbols[rdm.Next(symbols.Length)]);
            }
        }
        textBox1.Text = password.ToString();
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {

    }
}

5 个答案:

答案 0 :(得分:2)

您的密码生成过程分为两个步骤。

  1. 确定字符集
  2. 从长度为n的字符集中随机创建密码

功能1创建字符集:

// Make sure you have using System.Linq;
private List<char> GetCharacterSet()
{
    IEnumerable<char> returnSet = new char[]{};

    if (small_letters__Box.Checked)
    {
        returnSet = returnSet.Append(lower_chars);
    }

    if (capital_letters__Box.Checked)
    {
        returnSet = returnSet.Append(capital_chars);
    }

    if (numbers_Box.Checked)
    {
        returnSet = returnSet.Append(numbers);
    }

    if (symbols_Box.Checked)
    {
        returnSet = returnSet.Append(symbols);
    }

    return returnSet.ToList();
}

功能2从您的字符集中创建给定长度的密码

private string GetPassword(int length, List<char> characterSet)
{
    if(characterSet.Count < 1)
    {
        throw new ArgumentException("characterSet contains no items!");
    }

    if(length < 1)
    {
        return "";
    }

    Random rdm = new Random();

    StringBuilder password = new StringBuilder();

    for(int i = 0; i < length; i++){
        int charIndex = rdm.Next(0, characterSet.Count)
        password.Append(characterSet[charIndex]);
    }

    return password.ToString();
}

然后只需绑定您的按钮单击事件处理程序即可调用这些函数并显示生成的密码。

答案 1 :(得分:1)

下面的代码是我已经写了几年以上的代码,但我仍然在需要的许多项目中使用它,它满足了您的所有需求

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;

public static class ArrayExtentions
{
    public static object[] Shuffle(this object[] array)
    {
        var alreadySwaped = new HashSet<Tuple<int, int>>();
        var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(array.Length / 4), Convert.ToInt32((array.Length / 2) + 1));

        for (var i = 0; i <= rndLoopCount; i++)
        {
            int rndIndex1 = 0, rndIndex2 = 0;
            do
            {
                rndIndex1 = RandomUtils.GetRandom(0, array.Length);
                rndIndex2 = RandomUtils.GetRandom(0, array.Length);
            } while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));

            alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
            var swappingItem = array[rndIndex1];
            array[rndIndex1] = array[rndIndex2];
            array[rndIndex2] = swappingItem;
        }
        return array;
    }

}

public class RandomUtils
{
    private static readonly ThreadLocal<Random> RndLocal = new ThreadLocal<Random>(() => new Random(GetUniqueSeed()));

    private static int GetUniqueSeed()
    {
        long next, current;
        var guid = Guid.NewGuid().ToByteArray();
        var seed = BitConverter.ToInt64(guid, 0);

        do
        {
            current = Interlocked.Read(ref seed);
            next = current * BitConverter.ToInt64(guid, 3);
        } while (Interlocked.CompareExchange(ref seed, next, current) != current);

        return (int)next ^ Environment.TickCount;
    }

    public static int GetRandom(int min, int max)
    {
        Contract.Assert(max >= min);
        return RndLocal.Value.Next(min, max);
    }

    public static int GetRandom(int max)
    {
        return RndLocal.Value.Next(max);
    }

    public static double GetRandom()
    {
        return RndLocal.Value.NextDouble();
    }
}

public class StringUtility
{
    private const string UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
    private const string LowerAlpha = "abcdefghijklmnopqrstuwxyz";
    private const string Numbers = "0123456789";
    private const string SpecialChars = "~!@#$%^&*()_-+=.?";


    private static string CreateSourceString(bool includeLowerCase, bool includeUpperCase, bool includenumbers, bool includeSpChars)
    {
        Contract.Assert(includeLowerCase || includeUpperCase || includenumbers || includeSpChars);
        var sb = new StringBuilder();

        if (includeLowerCase) sb.Append(LowerAlpha);
        if (includeUpperCase) sb.Append(UpperAlpha);
        if (includenumbers) sb.Append(Numbers);
        if (includeSpChars) sb.Append(SpecialChars);
        return sb.ToString();
    }

    private static string GenerateString(string sourceString, int length = 6)
    {
        var rndString = Shuffle(sourceString);
        var builder = new StringBuilder();
        for (var i = 0; i < length; i++)
            builder.Append(rndString[RandomUtils.GetRandom(0, rndString.Length)]);
        return builder.ToString();
    }
    public static string GenerateRandomString(int length = 6,
        bool includenumbers = false,
        bool includeSpChars = false)
    {
        var sourceStr = CreateSourceString(true, true, includenumbers, includeSpChars);
        return GenerateString(sourceStr, length);
    }


    public static string GenerateRandomString(int minLength,
        int maxLength,
        bool includenumbers = false,
        bool includeSpChars = false)
    {
        if (maxLength < minLength) maxLength = minLength;
        var len = RandomUtils.GetRandom(minLength, maxLength + 1);
        return GenerateRandomString(len, includenumbers, includeSpChars);
    }

    public static string Shuffle(string str)
    {
        var alreadySwaped = new HashSet<Tuple<int, int>>();
        var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(str.Length / 4), Convert.ToInt32((str.Length / 2) + 1));
        var strArray = str.ToArray();
        for (var i = 0; i <= rndLoopCount; i++)
        {
            int rndIndex1 = 0, rndIndex2 = 0;
            do
            {
                rndIndex1 = RandomUtils.GetRandom(0, str.Length);
                rndIndex2 = RandomUtils.GetRandom(0, str.Length);
            } while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));

            alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
            var swappingChar = strArray[rndIndex1];
            strArray[rndIndex1] = strArray[rndIndex2];
            strArray[rndIndex2] = swappingChar;
        }
        return new string(strArray);
    }

    public static string GeneratePassword(PasswordComplexity complexityLevel)
    {
        switch (complexityLevel)
        {
            case PasswordComplexity.Simple: return GenerateSimplePassword();
            case PasswordComplexity.Medium: return GenerateMediumPassword();
            case PasswordComplexity.Strong: return GenerateStrongPassword();
            case PasswordComplexity.Stronger: return GenerateStrongerPassword();
        }
        return null;
    }

    private static string GenerateSimplePassword()
    {
        return GenerateRandomString(6, 9);
    }

    private static string GenerateMediumPassword()
    {
        var passLen = RandomUtils.GetRandom(6, 10);
        var numCount = RandomUtils.GetRandom(1, 3);
        var alphaStr = GenerateRandomString(passLen - numCount);
        var numStr = GenerateString(Numbers, numCount);
        var pass = alphaStr + numStr;
        return Shuffle(pass);
    }

    private static string GenerateStrongPassword()
    {
        var lowerCharCount = RandomUtils.GetRandom(2, 5);
        var upperCharCount = RandomUtils.GetRandom(2, 5);
        var numCount = RandomUtils.GetRandom(2, 4);
        var spCharCount = RandomUtils.GetRandom(2, 4);

        var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
        var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
        var spCharStr = GenerateString(SpecialChars, spCharCount);
        var numStr = GenerateString(Numbers, numCount);
        var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
        return Shuffle(pass);
    }

    private static string GenerateStrongerPassword()
    {
        var lowerCharCount = RandomUtils.GetRandom(5, 12);
        var upperCharCount = RandomUtils.GetRandom(4, 8);
        var numCount = RandomUtils.GetRandom(4, 6);
        var spCharCount = RandomUtils.GetRandom(4, 6);

        var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
        var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
        var spCharStr = GenerateString(SpecialChars, spCharCount);
        var numStr = GenerateString(Numbers, numCount);
        var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
        return Shuffle(Shuffle(pass));
    }

    public enum PasswordComplexity
    {
        Simple, Medium, Strong, Stronger
    }
}

答案 2 :(得分:0)

我为您编写了此代码。您可以复制并使用它。我所有的代码只是一个可以传递适当参数的方法,它为您提供了完全随机的密码。在回答您的问题之前,我已经对其进行了多次测试,效果很好。

private string GeneratePassword(bool useCapitalLetters, bool useSmallLetters, bool useNumbers, bool useSymbols, int passLenght)
    {
        Random random = new Random();

        StringBuilder password = new StringBuilder(string.Empty);

        //This for loop is for selecting password chars in order 
        for (int i = 0;;)
        {
            if (useCapitalLetters)
            {
                password.Append((char)random.Next(65, 91)); //Capital letters 
                ++i; if (i >= passLenght) break;
            }
            if (useSmallLetters)
            {
                password.Append((char)random.Next(97, 122)); //Small letters
                ++i; if (i >= passLenght) break;
            }
            if (useNumbers)
            {
                password.Append((char)random.Next(48, 57)); //Number letters
                ++i; if (i >= passLenght) break;
            }
            if (useSymbols)
            {
                password.Append((char)random.Next(35, 38)); //Symbol letters
                ++i; if (i >= passLenght) break;
            }
        }

        //This for loop is for disordering password characters
        for (int i = 0; i < password.Length; ++i)
        {
            int randomIndex1 = random.Next(password.Length);
            int randomIndex2 = random.Next(password.Length);
            char temp = password[randomIndex1];
            password[randomIndex1] = password[randomIndex2];
            password[randomIndex2] = temp;
        }

        return password.ToString();
    }

答案 3 :(得分:0)

去那里:

        string[] charList =
        {
            "abcdefghijklmnopqrstuvwxyz",
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
            "0123456789",
            "@\"!#$%&*@\\"
        };

        int desiredPasswordLength = 12;
        var randomNumberGenerator = new Random();
        string generatedPassword = "";

        for (int i = randomNumberGenerator.Next() % 4; desiredPasswordLength > 0; i = (i+1) % 4)
        {

            var takeRandomChars = randomNumberGenerator.Next() % 3;
            for (int j = 0; j < takeRandomChars; j++)
            {
                var randomChar = randomNumberGenerator.Next() % charList[i].Length;
                char selectedChar = charList[i][randomChar % charList[i].Length];
                generatedPassword = string.Join("", generatedPassword, selectedChar);
            }

            desiredPasswordLength -= takeRandomChars;
        }

        Console.WriteLine("Generated password: {0}",generatedPassword);

答案 4 :(得分:0)

一个完全随机化char和使用char最大重复的答案,我添加了一个shuffle字符串函数:

        const int Maximum_Identical = 2; // Max number of identical characters in a row 
        const string lower_chars = "abcdefghijklmnopqrstuvwxyz"; // lower case chars
        const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //capital chars
        const string numbers = "0123456789"; //numbers
        const string symbols = @"!#$%&*@\"; //symbols
        int lenght = 6; //

        bool lowercase = true, capital=true, num=true, sym=true;

        List<char[]> PasswordSet = new List<char[]>();
        List<char[]> charSet = new List<char[]>();
        List<int[]> countSet = new List<int[]>();

        if (lowercase) charSet.Add(lower_chars.ToArray());
        if (capital) charSet.Add(capital_chars.ToArray());
        if (num) charSet.Add(numbers.ToArray());
        if (sym) charSet.Add(symbols.ToArray());

        foreach(var c in charSet)
            countSet.Add(new int[c.Length]);

        Random rdm = new Random();
        //we create alist with each type with a length char (max repeat char included)
        for(int i = 0; i < charSet.Count;i++)
        {
            var lng = 1;
            var p0 = "";
            while (true)
            {
                var ind = rdm.Next(0, charSet[i].Length);
                if (countSet[i][ind] < Maximum_Identical )
                {
                    countSet[i][ind] += 1;
                    lng++;
                    p0 += charSet[i][ind];
                }
                if (lng == lenght) break;
            }
            PasswordSet.Add(p0.ToArray());
        }

        //generate a password with the desired length with at less one char in desired type,
        //and we choose randomly in desired type to complete the length of password
        var password = "";
        for(int i = 0; i < lenght; i++)
        {
            char p;
            if (i < PasswordSet.Count)
            {                   
                int id;
                do
                {
                    id = rdm.Next(0, PasswordSet[i].Length);
                    p = PasswordSet[i][id];
                } while (p == '\0');
                password += p;
                PasswordSet[i][id] = '\0';
            }
            else
            {
                int id0;
                int id1;
                do
                {
                    id0 = rdm.Next(0, PasswordSet.Count);
                    id1 = rdm.Next(0, PasswordSet[id0].Length);
                    p = PasswordSet[id0][id1];
                } while (p == '\0');
                password += p;
                PasswordSet[id0][id1] = '\0';
            }
        }

        //you could shuffle the final password
        password = Shuffle.StringMixer(password);

随机播放字符串函数:

static class Shuffle
{
    static System.Random rnd = new System.Random();

    static void Fisher_Yates(int[] array)
    {
        int arraysize = array.Length;
        int random;
        int temp;

        for (int i = 0; i < arraysize; i++)
        {
            random = i + (int)(rnd.NextDouble() * (arraysize - i));

            temp = array[random];
            array[random] = array[i];
            array[i] = temp;
        }
    }

    public static string StringMixer(string s)
    {
        string output = "";
        int arraysize = s.Length;
        int[] randomArray = new int[arraysize];

        for (int i = 0; i < arraysize; i++)
        {
            randomArray[i] = i;
        }

        Fisher_Yates(randomArray);

        for (int i = 0; i < arraysize; i++)
        {
            output += s[randomArray[i]];
        }

        return output;
    }
}