Подтверждение членства. GeneratePassword - PullRequest
0 голосов
/ 30 апреля 2019

Я использую Membership.GeneratePassword () для генерации случайного пароля. Иногда возвращаемое значение не соответствует необходимым требованиям проверки. Пользователь также может предоставить пароль, отсюда и требования к валидации.

Я в основном хочу проверить возвращенный пароль, если он не содержит прописных букв, строчных букв и цифр, а затем сгенерирует еще один.

Иногда мой чек вернет true, тогда как, очевидно, нет.

Я попытался использовать RegEx и некоторые ссылки LINQ следующим образом:

string generatePassword()
{
    password =  System.Web.Security.Membership.GeneratePassword(16, 8);

    if (password.Any(c => char.IsUpper(c)) && password.Any(c => char.IsDigit(c)) && password.Any(c => char.IsLower(c)))
    {
        return password;
    }
    else
    {
       generatePassword();
    }
}


void test() {
    var pattern = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*()_\-+=[{\]};:<>|.\/\?])(?=.{8,})";

    var count = 0;
    for (var i = 0; i < 10000; i++)
    {
        var password = generatePassword();
        if (!Regex.Match(password, pattern).Success)
        {
             Console.WriteLine(password);
             count++;
        }
    }

    Console.WriteLine("There were {0} non matches", count);
}

На мой взгляд, приведенное выше всегда должно возвращать действительный пароль. У меня есть странный сценарий, в котором он вернет пароль без цифры, поэтому проверка не пройдена, но если я сделаю то же самое passowrd.Any(char.IsDigit) внутри test для возвращенного пароля, он скажет true.

Если это поможет, пароль должен содержать не менее 8 цифр, содержать заглавные, строчные буквы, цифры и специальный символ: !@#$%^&*()_-+=[{]};:<>|./?

Спасибо.

1 Ответ

0 голосов
/ 30 апреля 2019

Возможно, ваше регулярное выражение является допустимым, но я думаю, что действительно трудно понять, что оно делает.

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

Я запрограммирую это как методы расширения строки.Если вы решите, что ваш пароль больше не является строкой, изменения будут минимальными.См. Расширение методов расширения:

static bool IsSpecialChar(this char c)
{
    const string specialChars = "!@#$%^&*()_-+=[{]};:<>|./?";
    return specialChars.Contains(c);
}

static bool IsValidPassword(this string password)
{
    // the password needs to be at least 8 characters,
    // contain an uppercase, lowercase, digit and a special char

    // TODO: exception if password == null;
    if (password.Length < 8) return false;

    bool uppercaseDetected = false;
    bool lowercaseDetected = false;
    bool digitDetected = false;
    bool specialCharDetected = false;

    using (IEnumerator<char> enumerator = password.GetEnumerator())
    {
        while (enumerator.MoveNext
           && !(uppercaseDetected && lowercaseDetected 
                 && digitDetected && specialCharDetected))
        {
            // a character is available, and we still don't know if it is a proper password
            char c = enumerator.Current;
            uppercaseDetected = uppercaseDetected || Char.IsUpperCase(c);
            lowercaseDetected = lowercaseDetected || Char.IsLowerCase(c);
            digitDetected = digitDetected || Char.IsDigit(c);
            specialCharDetected = specialCharDetected || c.IsSpecialChar();
        }

        return uppercaseDetected && lowercaseDetected 
            && digitDetected && specialCharDetected;
    }
}

Использование:

string GeneratePassword()
{
    string proposedPassword = ...;
    while (!proposedPassword.IsValidPassword())
    {
        proposedPassword = ...;
    }
}

Чтобы убедиться, что оно заканчивается, вы можете добавить счетчик и остановиться после 1000 попыток;или просто добавьте случайный Uppercase / LowerCase / SpecialChar

...