Как создать случайный пароль, который соответствует требованию конкретных символов? - PullRequest
0 голосов
/ 14 июня 2019

Мне нужно создать случайный пароль, но он соответствует некоторым конкретным параметрам:

Должен иметь майус

Должен иметь числа

В нем должны быть специальные символы.

Не может содержать следующие строки "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 введите описание изображения здесь

Ответы [ 2 ]

4 голосов
/ 14 июня 2019

Ваш переполнение стека связано с тем, что у вас неограниченная рекурсия.Помните, что рекурсивная программа АБСОЛЮТНО ДОЛЖНА иметь свойство, что рекурсивный шаг - это меньшая проблема.Вы дали вашему рекурсивному шагу проблему одинакового размера, и она может никогда не остановиться.

Правильный способ написания вашей программы - написать два метода:

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**
}

Ваш код длясоздать случайный пароль во многих отношениях плохо, но ваш вопрос касался решения проблемы переполнения стека.Это решит переполнение стека.Работайте над улучшением генератора случайных паролей своим собственным методом.

0 голосов
/ 14 июня 2019

Проблема, с которой вы столкнулись, связана с двумя вещами:

Прежде всего, вы используете рекурсию для генерации вашего пароля, и я могу сказать на опыте, что это может привести к неприятному переполнению стека, нопричина того, что вы получаете это переполнение стека, заключается в том, что вы никогда не генерируете действительный пароль, вероятно, поэтому функция никогда не заканчивается, и причина в том, что каждый раз, когда вы вызываете свою функцию CrearPassword, вы генерируете новый Random, и это, вероятно, занимает то же времяПоскольку случайная функция использует время в качестве начального числа, вы, вероятно, получаете одно и то же начальное число и всегда получаете неверный пароль.

Что вы можете сделать тогда?

Хорошо для начала, если вы настаиваете на использованиислучайный, вытащите его из функции, сделайте его глобальной переменной и просто вызовите rnd.Next из вашей функции.Во-вторых, вы должны создать еще одну функцию, связанную с созданием, и переименовать этот CreatePassword в SuggestPassword.Просто, чтобы поместить это в код, это мое предложение.

public void CreateRandomPassword()
{
    while(true)
    {
        string pass = CrearPassword(8, "user");
        if(ValidPassword(pass, "user"))
        {
            break;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...