Проверка строк на наличие достаточно надежного пароля

Возможный дубликат:
Надежное регулярное выражение для пароля
Нужен RegEx для надежности пароля?

Мне просто было интересно, какой лучший способ поиска строки по определенным критериям (в частности, надежность пароля) может быть выполнен.

Пока у меня простой:

if(password.Length <= 7)
    {
        errorMessage = "Your password must be at least 8 characters.";
    }

Я хотел бы иметь возможность проверять заглавные буквы, но я не уверен, что это за метод или процедура. Я попытался воспользоваться поиском в Google, выполнить поиск на веб-сайте: http://msdn.microsoft.com и выполнить поиск в индексе моего Книга C# (C# Programming 3E, Barbara Doyle), но я не могу ее найти.

Я знаю, что могу попробовать это...:

foreach(char c in password)
    {
        if(c!='A' || c!='B' || c!='C' || c!='D' ..... || c!='Z')
        {
            errorMessage = "Your password must contain at least one capital letter";
        }
    }

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

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

В любом случае, большое спасибо за любую помощь, которую может оказать любой.


person VoidKing    schedule 15.10.2012    source источник
comment
Это не ответ, но убедитесь, что вы понимаете xkcd.com/936 и xkcd.com/792 И я также рекомендую прочитать codinghorror.com/blog/2010/12/ и поиск на сайте Джеффа других статей по теме. Затем посмотрите на Регулярные выражения для проверки соответствующей длины/сложности.   -  person David    schedule 15.10.2012
comment
Вместо ряда предложений if...then вы, вероятно, захотите ввести пароль через регулярное выражение. Взгляните на этот ответ SO. Я думаю, что это обеспечивает регулярное выражение, которое поможет вам.   -  person David Hoerster    schedule 15.10.2012
comment
@DarinDimitrov Эй, спасибо за это, я не видел эту ссылку, потому что не знал, что нужно искать регулярное выражение (хотя, думаю, это очевидно). Мои извинения и спасибо за ссылку!   -  person VoidKing    schedule 15.10.2012
comment
Я категорически не согласен с решением закрыть этот вопрос как дубликат, ссылаясь только на вопросы, касающиеся регулярных выражений. ОП явно не запрашивал ответ регулярного выражения, и некоторые люди могут не счесть использование регулярного выражения лучшим ответом, поскольку не все могут легко понять регулярные выражения.   -  person Aerik    schedule 14.02.2019


Ответы (1)


Я не могу взять на себя ответственность, так как я украл это из здесь

using System.Text;
using System.Text.RegularExpressions;

  public enum PasswordScore
  {
    Blank = 0,
    VeryWeak = 1,
    Weak = 2,
    Medium = 3,
    Strong = 4,
    VeryStrong = 5
  }

  public class PasswordAdvisor
  {
    public static PasswordScore CheckStrength(string password)
    {
      int score = 0;

      if (password.Length < 1)
        return PasswordScore.Blank;
      if (password.Length < 4)
        return PasswordScore.VeryWeak;

      if (password.Length >= 8)
        score++;
      if (password.Length >= 12)
        score++;
      if (Regex.Match(password, @"/\d+/", RegexOptions.ECMAScript).Success)
        score++;
      if (Regex.Match(password, @"/[a-z]/", RegexOptions.ECMAScript).Success &&
        Regex.Match(password, @"/[A-Z]/", RegexOptions.ECMAScript).Success)
        score++;
      if (Regex.Match(password, @"/.[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]/", RegexOptions.ECMAScript).Success)
        score++;

      return (PasswordScore)score;
    }
  }

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

** Обновлять **

Я знаю, что вопрос закрыт, но я могу добавить больше объяснений для VoidKing, чтобы понять некоторые концепции.

Метод CheckStrength возвращает значение PasswordScore, которое можно использовать в качестве условия дальнейших действий в коде.

Вот непроверенная демонстрация того, как можно использовать приведенный выше код:

String password = "MyDummy_Password"; // Substitute with the user input string
PasswordScore passwordStrengthScore = PasswordAdvisor.CheckStrength(password);

switch (passwordStrengthScore) {
    case PasswordScore.Blank:
    case PasswordScore.VeryWeak:
    case PasswordScore.Weak:
            // Show an error message to the user
            break;
    case PasswordScore.Medium:
    case PasswordScore.Strong:
    case PasswordScore.VeryStrong:
           // Password deemed strong enough, allow user to be added to database etc
           break;
}

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

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

person Steve Kennaird    schedule 15.10.2012
comment
Чувак, ты заслуживаешь репутации просто за то, насколько это полезно в целом... До сих пор я понятия не имел, как они оценивают пароли по такой шкале... Спасибо! - person VoidKing; 15.10.2012
comment
Как именно работает это регулярное выражение? Я хотел бы иметь возможность сделать свой собственный. Прав ли я, предполагая, что он проверяет каждый символ (и последующие символы, если предыдущий совпадает) на совпадения в предоставленной строке регулярного выражения? (простите меня, если я неправильно использую регулярное выражение, грамматически говоря) - person VoidKing; 15.10.2012
comment
Ну, я пробовал это, но я просто недостаточно знаю об этой процедуре. Я только что начал переходить к внешним файлам .cs (или использовать их или как-то иначе), и я могу это сделать, но я не могу работать ни с какими данными, которые должен предоставлять этот класс. У меня никогда не бывает достаточно кода, я также должен понимать его, чтобы реализовать его в своих приложениях, и я просто сказал: «Не надо». Что такое ECMAScript? почему перечисление? какие данные возвращаются? (Я обнаружил, что не могу превратить его во что-нибудь полезное). В любом случае, спасибо за попытку помочь. - person VoidKing; 15.10.2012
comment
Я обновил ответ, чтобы помочь вам в дальнейшем. Надеюсь, вы найдете ее полезной. - person Steve Kennaird; 16.10.2012
comment
Мне это нравится, хотя я бы начал с 0, чтобы использовать еще более надежные пароли. Как сейчас, 12345678 будет оцениваться как средняя сила, с чем я действительно не согласен. :-) - person Nikolaj Dam Larsen; 17.07.2014
comment
Пароль как Password@123 создаст PasswordScore как 6, который не определен в enum. Таким образом, оценка должна начинаться с 0, чтобы сделать ее более надежной. - person Sumit Gupta; 06.08.2014
comment
Мне пришлось убрать замыкающий/ведущий /s, чтобы заставить это работать. - person Paul Knopf; 04.02.2015
comment
Хотя это хорошо, по сути, это +1 для любого из следующего (длина › 8, длина › 12, имеет строчные буквы алфавита, имеет прописные буквы алфавита, имеет цифру, имеет специальный символ.) Потому что большинство логика находится в регулярных выражениях, ее легко расширить до javascript. Единственная проблема заключается в том, что он не проверяет общие слова/последовательности и т. д. Нельзя сказать, что это не очень хорошее решение, просто его нужно воспринимать с долей… скептицизма. - person user420667; 25.06.2016
comment
Не будет ли String.IsNullOrEmpty(password) иметь больше смысла, чем password.Length < 1? - person Deantwo; 02.05.2017
comment
@SumitGupta На самом деле отсутствует значение enum, оценка должна начинаться с 1, иначе password.Length < 4 и password.Length >= 8 вернут значение PasswordScore.VeryWeak. Я добавил значение PasswordScore.TooShort = 1 и вернул его, если password.Length < 4. Все остальные значения enum должны быть увеличены на единицу. Я отредактировал ответ с моими исправлениями - person JPelletier; 08.09.2017
comment
Я пытался отредактировать ответ с моими исправлениями, но, похоже, он был отклонен :( если вы скопируете / вставите код, прочитайте мой комментарий выше - person JPelletier; 11.09.2017
comment
Я бы добавил + и =. - person Garr Godfrey; 24.10.2020
comment
@JPelletier Я не уверен, что ›=8 очень слаб, это проблема, но определенно есть проблема с паролями длиной 5,6 и 7, возвращающими пустое значение (если у них нет других качеств) - person Garr Godfrey; 24.10.2020