如何创建符合特定字符要求的随机密码?

时间:2019-06-13 21:48:33

标签: c# visual-studio

我需要创建一个随机密码,但是它符合某些特定参数:

必须有蛋黄酱

必须有数字

必须有特殊字符。

它不能包含以下字符串“ 123”,“ 12345”,“ 56789”,“ 123456789”,“ 321”,“ 54321”,“ 987654321”,“ qwerty”,“ asdf”,“ zxcv”, “ poiuy”,“ lkjhg”,“ mnbv”

还有。

我已经用以下代码做到了,但是它引发了我StackOberflowException错误,我可以通过什么其他方式实现它,或者该错误的解决方案是什么?

public static string CrearPassword(int longitud,string usuario)
    {
        string caracteres = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ1234567890ñÑ-_¿.#¡";
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < longitud--)
        {
            res.Append(caracteres[rnd.Next(caracteres.Length)]);
        }

        while (ValidPassword(res.ToString(), usuario)== false)
        { 
            return CrearPassword(13,usuario);
        }
        return res.ToString();
    }

    public static bool ValidPassword(string pass, string usuario)
    {
        try
        {
            Match matchLongitud = Regex.Match(pass, @"^\w{8,15}\b");
            Match matchNumeros = Regex.Match(pass, @"\d");
            Match matchEspeciales = Regex.Match(pass, @"[ñÑ\-_¿.#¡]");
            Match matchMayusculas = Regex.Match(pass, @"[A-Z]");
            Match matchAdmin = Regex.Match(pass, @"admin");
            Match matchContraseña = Regex.Match(pass, @"contraseña");
            Match matchNombreUsuario = Regex.Match(pass, usuario);
            var valoresProhibidos = new List<string>() { "123", "12345", "56789", "123456789", "321", "54321", "987654321", "qwerty", "asdf", "zxcv", "poiuy", "lkjhg", "mnbv" };

            if (!matchNumeros.Success)
                return false;
            else if (!matchLongitud.Success)
                return false;
            else if (!matchEspeciales.Success)
                return false;
            else if (!matchMayusculas.Success)
                return false;
            else if (matchAdmin.Success)
                return false;
            else if (matchContraseña.Success)
                return false;
            else if (matchNombreUsuario.Success)
                return false;
            else
            {
                foreach (string valor in valoresProhibidos)
                {
                    if (pass.Contains(valor))
                    {
                        return false;
                    }
                }
            }

            return true;

应该验证并返回密码,但是从SystemStackOverflowException中提取错误 enter image description here

2 个答案:

答案 0 :(得分:4)

您的堆栈溢出是因为您有无限的递归。请记住,递归程序绝对必须具有以下性质:递归步骤是一个更小问题。您已经为递归步骤设置了同样大小的问题,它可能永远不会停止。

编写程序的正确方法是编写两种方法:

public static string CreateValidPassword(int longitud, string usuario)
{
  while(true)
  {
    var password = CreateRandomPassword(longitud, usuario);
    if (ValidPassword(password)) 
      return password;
  }
}

public static string CreateRandomPassword(int longitud, string usuario)
{ 
  // Create a random password **CORRECTLY THIS TIME**
}

您创建随机密码的代码在许多方面都是不好的,但是您的问题是关于解决堆栈溢出的问题。这将解决堆栈溢出。用自己的方法改进随机密码生成器。

答案 1 :(得分:0)

您遇到的问题与两件事有关:

首先,您正在使用递归生成密码,并且我可以告诉您经验可能会导致讨厌的堆栈溢出,但是导致此堆栈溢出的原因是因为您从未生成有效的密码可能因此函数永无止境,原因是,每次调用函数CrearPassword时,您都会生成一个新的Random,并且它可能花费相同的时间,因为random函数使用时间作为种子,您可能会获得相同的种子并总是获得无效的密码。

那你能做什么?

如果您坚持使用随机数,将其从函数中取出,使其成为全局变量,然后从函数中调用rnd.Next,那么对于初学者来说是个好方法。其次,您应该创建另一个处理创建的功能,并将该创建密码重命名为建议密码。只是将其放入代码中,这是我的建议。

public void CreateRandomPassword()
{
    while(true)
    {
        string pass = CrearPassword(8, "user");
        if(ValidPassword(pass, "user"))
        {
            break;
        }
    }
}