2009-07-20 7 views
2

Angenommen, ich habe eine Regex, die nach alphanumerischen Zeichen sucht.Erstellen einer Regex, um nach einem starken Passwort zu suchen

Ich möchte jetzt eine andere Regex erstellen, die nach mindestens 1 Nummer im Passwort sucht. Und ich möchte überprüfen, ob es mindestens 1 nicht-alphanumerische Zeichen (etwas anderes als ein Buchstabe oder eine Zahl) hat.

Sollte ich nur jeden einzeln anrufen, und wenn einer fehlschlägt, false zurück oder gibt es eine Möglichkeit, sie in 1 Anruf zu kombinieren?

+0

Besser, jeden Check in separate Funktion zu halten - Code wird besser lesbar sein –

Antwort

3

Hängt genau auf, welche Kriterien Sie verwenden, aber es wäre wahrscheinlich besser, einen einzigen Durchlauf durch die Zeichenfolge zu tun, und eine Anzahl von Flags basiert gesetzt, was Sie haben gesehen:

  • hasDigit
  • hasAlpha
  • hasSymbol
  • etc

Dann verwenden Sie diese am Ende, um zu entscheiden, ob das Passwort komplex genug ist.

noch besser:

Wie Lexu schon sagt, zählt statt Fahnen mit würde eine größere Flexibilität ermöglichen.

+1

Ich mag die Idee (und sie beantwortet die gestellte Frage!), Aber ich würde vorschlagen, Digits, Aplha, Symbol zu zählen, anstatt jeweils eine einzelne Flagge zu setzen. Dies ermöglicht den nächsten Schritt -> die PWD-Stärke zu bewerten. – lexu

+0

Sehr guter Punkt – Draemon

0

Sie fügen ein | hinzu (oder) Operator in die Regex z.B.

[0-9] | [AZ]

+0

'[A-Z0-9]' würde genauso gut funktionieren. – Noldorin

+0

Stimmt, aber ich fühle mich immer besser, das | zu verwenden um sie zu teilen, so ist es klarer, was los ist – James

+1

Eigentlich würde diese Aussage nicht funktionieren, weil sie das erforderliche AND nicht implementiert. Dieser Regexp wird ausgelöst, wenn ein Großbuchstabe ODER ein Zahlenwert vorhanden ist. Angefordert wurden "eine oder mehrere Ziffern UND ein oder mehrere nicht-alphanumerische Zeichen". –

1

Sie sollten zwei Anrufe verwenden. Für etwas fortgeschrittenere Tests können Sie die password meter verwenden. Es ist frei verfügbar für den Vertrieb unter GPL.

3

würde ich kleine Methoden komponiert mit & &:

internal bool HasDigit(string password) { .. } 
internal bool HasNonAlpha(string password) { .. } 

bool IsStrong(string password) { 
    return HasDigit(password) && HasNonAlpha(password); 
} 
1

IMHO, es ist eine Frage des Stils, ob aus ihm eine oder zwei Aussagen zu machen.

Warum nicht in einer der beiden Reihenfolgen darauf achten, dass sie erscheinen. (Wie reguläre Ausdrücke gehen, haben wir nicht so etwas wie ein Zähler für Zahnspangen oder Klammern, so müssen wir die mögliche Ordnung der Dinge ehren

Das könnte man für Perl arbeiten.

(\d.*[^[:alnum:]])|([^[:alnum:]].*\d)

Might . jeder semantischer Zustand einmal werden leichter zu lesen zwei Aussagen zu machen, vor allem, weil dann nur auftritt

+0

Hey, schau mal: Jemand hat die Frage tatsächlich beantwortet. Es sollte mehr Upvotes geben. –

+0

Eigentlich ist dies nicht unbedingt eine Antwort (weil es nicht C# ist), aber ich denke, Regexps überall sind meist Perl-Syntax. (Wenigstens stolpern Sie über "see perl regexp doc für Details" hin und wieder.) –

2

ich denke, das ist das, was Sie suchen:

^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$ 
public bool PasswordOk(string pwd) 
{ 
    return Regex.IsMatch(pwd,@"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$"); 
} 
+0

Ich dachte, es wäre eine schlechte Idee, eine unendliche Wiederholung in einem Look-Behind zu haben. Ich nehme an, es ist keine große Sache für eine kleine Probe. –

+0

Ein Passwort ist eine kleine Probe, also denke ich, es ist eine vollkommen akzeptable Lösung für die einfache Passwort-Validierung. –

0

Regex ist nicht der schnellste Weg:

In Code (wird mit mindestens einer Ziffer und einem nicht-alphanumerische Zeichen mit einer Mindestlänge von 6, ein Passwort übereinstimmen).

Geben Sie diesen einen Versuch:

string Password = "Pass12!"; 

bool ValidPassword = Password.Any(char.IsDigit) 
    && !Password.All(char.IsLetterOrDigit) 
    && Password.Length >= 6; 

Statt:

string Password = "Pass12!"; 

bool ValidPassword = Regex.IsMatch(Password, @"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$"); 

ich Sie es 1 Million mal durchlaufen sie die erste 157ms und die zweite 1251ms nehmen.

Und das Wichtigste, was die anderen schon sagten: viel besser zu pflegen.