webentwicklung-frage-antwort-db.com.de

Regulärer Ausdruck für die Kennwortüberprüfung

Derzeit verwende ich diesen regulären Ausdruck, um zu überprüfen, ob eine Zeichenfolge einige Bedingungen erfüllt.

Die Bedingungen sind String muss zwischen 8 und 15 Zeichen lang sein. string muss mindestens eine Zahl enthalten. String muss mindestens einen Großbuchstaben enthalten. string muss mindestens einen Kleinbuchstaben enthalten. 

(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,15})$

Es funktioniert größtenteils, erlaubt aber keine Sonderzeichen. Jede Hilfe, die diesen Regex ändert, um Sonderzeichen zuzulassen, wird sehr geschätzt.

43
desi

Hier scheint viel Verwirrung zu herrschen. Die Antworten, die ich bisher sehe, erzwingen die 1+ -Nummer/1 + Kleinbuchstaben/1 + Großbuchstabenregel nicht richtig, was bedeutet, dass Kennwörter wie abc123, 123XYZ oder AB * & ^ # würde immer noch akzeptiert. Das Vermeiden von Kleinbuchstaben, Großbuchstaben oder Ziffern ist nicht ausreichend. Sie müssen die Anwesenheit von mindestens einem von jedem erzwingen.

Versuche Folgendes:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,15}$

Wenn Sie auch mindestens einen Sonderzeichen benötigen (was wahrscheinlich eine gute Idee ist), versuchen Sie Folgendes:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$

Der .{8,15} kann auf Wunsch restriktiver gestaltet werden (Sie könnten ihn beispielsweise in \S{8,15} ändern, um Leerzeichen nicht zuzulassen). Denken Sie jedoch daran, dass dadurch die Stärke Ihres Kennwortschemas verringert wird.

Ich habe dieses Muster getestet und es funktioniert wie erwartet. Getestet auf ReFiddle hier: http://refiddle.com/110


Edit: Eine kleine Anmerkung, die einfachste - Methode, ist dies mit 3 separaten Regexen und der Length-Eigenschaft des Strings. Es ist auch einfacher zu lesen und zu pflegen, also machen Sie es auf diese Weise, wenn Sie die Option haben. Wenn dies jedoch für Validierungsregeln in Markup gilt, bleiben Sie wahrscheinlich bei einem einzelnen Regex.

79
Justin Morgan

Ist ein regulärer Ausdruck eine einfachere/bessere Möglichkeit, eine einfache Einschränkung durchzusetzen als die offensichtlichere Methode?

static bool ValidatePassword( string password )
{
  const int MIN_LENGTH =  8 ;
  const int MAX_LENGTH = 15 ;

  if ( password == null ) throw new ArgumentNullException() ;

  bool meetsLengthRequirements = password.Length >= MIN_LENGTH && password.Length <= MAX_LENGTH ;
  bool hasUpperCaseLetter      = false ;
  bool hasLowerCaseLetter      = false ;
  bool hasDecimalDigit         = false ;

  if ( meetsLengthRequirements )
  {
    foreach (char c in password )
    {
      if      ( char.IsUpper(c) ) hasUpperCaseLetter = true ;
      else if ( char.IsLower(c) ) hasLowerCaseLetter = true ;
      else if ( char.IsDigit(c) ) hasDecimalDigit    = true ;
    }
  }

  bool isValid = meetsLengthRequirements
              && hasUpperCaseLetter
              && hasLowerCaseLetter
              && hasDecimalDigit
              ;
  return isValid ;

}

Welches ist Ihrer Meinung nach der Wartungsprogrammierer, der in drei Jahren, der die Einschränkung ändern muss, leichter zu verstehen ist?

40
Nicholas Carey

Sie können diese Methode ausprobieren:

private bool ValidatePassword(string password, out string ErrorMessage)
    {
        var input = password;
        ErrorMessage = string.Empty;

        if (string.IsNullOrWhiteSpace(input))
        {
            throw new Exception("Password should not be empty");
        }

        var hasNumber = new Regex(@"[0-9]+");
        var hasUpperChar = new Regex(@"[A-Z]+");
        var hasMiniMaxChars = new Regex(@".{8,15}");
        var hasLowerChar = new Regex(@"[a-z]+");
        var hasSymbols = new Regex(@"[[email protected]#$%^&*()_+=\[{\]};:<>|./?,-]");

        if (!hasLowerChar.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one lower case letter";
            return false;
        }
        else if (!hasUpperChar.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one upper case letter";
            return false;
        }
        else if (!hasMiniMaxChars.IsMatch(input))
        {
            ErrorMessage = "Password should not be less than or greater than 12 characters";
            return false;
        }
        else if (!hasNumber.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one numeric value";
            return false;
        }

        else if (!hasSymbols.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one special case characters";
            return false;
        }
        else
        {
            return true;
        }
    }
8
Anurag

Ich denke es sollte so sein:

(?!^[0-9]*$)(?!^[a-zA-Z]*$)^(.{8,15})$

Dies prüft die Einschränkungen mit Ihren Zeichenklassen und prüft dann, ob Sie zwischen 8 und 15 Zeichen haben. Welcher Charakter spielt keine Rolle mehr, weil Sie bereits geprüft haben, ob Ihre Einschränkungen übereinstimmen.

3
Daniel Hilgarth

Ich würde sie einzeln überprüfen; d. h. nach einer Nummer \d+ suchen. Wenn dies fehlschlägt, können Sie dem Benutzer mitteilen, dass er eine Ziffer hinzufügen muss. Dadurch wird vermieden, dass der Fehler "Ungültig" zurückgegeben wird, ohne dass der Benutzer darauf hingewiesen wird, was falsch ist.

2
Alex K.

Probieren Sie dies aus (auch korrigierte Prüfung auf Groß- und Kleinschreibung, es gab einen Fehler, da Sie sie als [a-zA-Z] gruppiert haben; es sucht nur nach mindestens einem Unter- oder Oberkopf.

(?!^[0-9]*$)(?!^[a-z]*$)(?!^[A-Z]*$)^(.{8,15})$

Update: Ich habe festgestellt, dass der Regex nicht wirklich wie erwartet funktioniert und so sollte es auch nicht geschrieben werden!

Versuchen Sie etwas so:

(?=^.{8,15}$)(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?!.*\s).*$

(Zwischen 8 und 15 einschließlich enthält mindestens eine Ziffer, mindestens ein Großbuchstabe und mindestens ein Kleinbuchstabe und kein Leerzeichen.)

Und ich denke, das ist auch einfacher zu verstehen.

2
manojlds

Lang und könnte vielleicht gekürzt werden. Unterstützt Sonderzeichen ?"-_.

\A(?=[-\?\"_a-zA-Z0-9]*?[A-Z])(?=[-\?\"_a-zA-Z0-9]*?[a-z])(?=[-\?\"_a-zA-Z0-9]*?[0-9])[-\?\"_a-zA-Z0-9]{8,15}\z
0
Ken White

Danke Nicholas Carey. Ich wollte zuerst Regex verwenden, aber was Sie geschrieben haben, hat meine Meinung geändert. Es ist so viel einfacher, diesen Weg aufrecht zu erhalten.

//You can set these from your custom service methods
int minLen = 8;
int minDigit 2;
int minSpChar 2;

Boolean ErrorFlag = false;
//Check for password length
if (model.NewPassword.Length < minLen)
{
    ErrorFlag = true;
    ModelState.AddModelError("NewPassword", "Password must be at least " + minLen + " characters long.");
}

//Check for Digits and Special Characters
int digitCount = 0;
int splCharCount = 0;
foreach (char c in model.NewPassword)
{
    if (char.IsDigit(c)) digitCount++;
    if (Regex.IsMatch(c.ToString(), @"[!#$%&'()*+,-.:;<=>[email protected][\\\]{}^_`|~]")) splCharCount++;
}

if (digitCount < minDigit)
{
    ErrorFlag = true;
    ModelState.AddModelError("NewPassword", "Password must have at least " + minDigit + " digit(s).");
}
if (splCharCount < minSpChar)
{
    ErrorFlag = true;
    ModelState.AddModelError("NewPassword", "Password must have at least " + minSpChar + " special character(s).");
}

if (ErrorFlag)
    return View(model);
0
Max