web-dev-qa-db-ja.com

パスワードの強度を検証する正規表現

私のパスワード強度の基準は次のとおりです。

  • 8文字の長さ
  • 大文字2文字
  • 1特殊文字(!@#$&*)
  • 2つの数字(0-9)
  • 小文字の3文字

誰かが私のために正規表現をお願いします。パスワードですべての条件を満たしている必要があります。

127
Ajay Kelkar

これらのチェックは、肯定的な先読みアサーションを使用して実行できます。

^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$

環状リンク

説明:

^                         Start anchor
(?=.*[A-Z].*[A-Z])        Ensure string has two uppercase letters.
(?=.*[!@#$&*])            Ensure string has one special case letter.
(?=.*[0-9].*[0-9])        Ensure string has two digits.
(?=.*[a-z].*[a-z].*[a-z]) Ensure string has three lowercase letters.
.{8}                      Ensure string is of length 8.
$                         End anchor.
385
codaddict

長さゼロの正の先読みを使用して、各制約を個別に指定できます。

(?=.{8,})(?=.*\p{Lu}.*\p{Lu})(?=.*[!@#$&*])(?=.*[0-9])(?=.*\p{Ll}.*\p{Ll})

正規表現エンジンが\p表記をサポートしておらず、純粋なASCIIで十分な場合は、\p{Lu}[A-Z]に、\p{Ll}[a-z]に置き換えることができます。

10
Joachim Sauer

上記の答えは完璧ですが、私はsuggest大きな正規表現ではなく複数の小さな正規表現を使用します。
長い正規表現の分割にはいくつかの利点があります。

  • 読み書きのしやすさ
  • デバッグのしやすさ
  • 正規表現の一部を追加/削除する容易さ

一般的に、このアプローチはコードを維持します簡単に保守可能

そうは言っても、例としてSwiftで記述したコードを共有します。

struct RegExp {

    /**
     Check password complexity

     - parameter password:         password to test
     - parameter length:           password min length
     - parameter patternsToEscape: patterns that password must not contains
     - parameter caseSensitivty:   specify if password must conforms case sensitivity or not
     - parameter numericDigits:    specify if password must conforms contains numeric digits or not

     - returns: boolean that describes if password is valid or not
     */
    static func checkPasswordComplexity(password password: String, length: Int, patternsToEscape: [String], caseSensitivty: Bool, numericDigits: Bool) -> Bool {
        if (password.length < length) {
            return false
        }
        if caseSensitivty {
            let hasUpperCase = RegExp.matchesForRegexInText("[A-Z]", text: password).count > 0
            if !hasUpperCase {
                return false
            }
            let hasLowerCase = RegExp.matchesForRegexInText("[a-z]", text: password).count > 0
            if !hasLowerCase {
                return false
            }
        }
        if numericDigits {
            let hasNumbers = RegExp.matchesForRegexInText("\\d", text: password).count > 0
            if !hasNumbers {
                return false
            }
        }
        if patternsToEscape.count > 0 {
            let passwordLowerCase = password.lowercaseString
            for pattern in patternsToEscape {
                let hasMatchesWithPattern = RegExp.matchesForRegexInText(pattern, text: passwordLowerCase).count > 0
                if hasMatchesWithPattern {
                    return false
                }
            }
        }
        return true
    }

    static func matchesForRegexInText(regex: String, text: String) -> [String] {
        do {
            let regex = try NSRegularExpression(pattern: regex, options: [])
            let nsString = text as NSString
            let results = regex.matchesInString(text,
                options: [], range: NSMakeRange(0, nsString.length))
            return results.map { nsString.substringWithRange($0.range)}
        } catch let error as NSError {
            print("invalid regex: \(error.localizedDescription)")
            return []
        }
    }
}
5
Luca Davanzo

追加することをお勧めします

(?!.*pass|.*Word|.*1234|.*qwer|.*asdf) exclude common passwords
2
Stuart

codaddictのソリューションは正常に機能しますが、これはもう少し効率的です:(Python構文)

password = re.compile(r"""(?#!py password Rev:20160831_2100)
    # Validate password: 2 upper, 1 special, 2 digit, 1 lower, 8 chars.
    ^                        # Anchor to start of string.
    (?=(?:[^A-Z]*[A-Z]){2})  # At least two uppercase.
    (?=[^!@#$&*]*[!@#$&*])   # At least one "special".
    (?=(?:[^0-9]*[0-9]){2})  # At least two digit.
    .{8,}                    # Password length is 8 or more.
    $                        # Anchor to end of string.
    """, re.VERBOSE)

否定された文字クラスは、単一のステップで目的の文字まですべてを消費し、バックトラッキングを必要としません。 (ドットスターソリューションは正常に機能しますが、ある程度のバックトラッキングが必要です。)もちろん、パスワードなどの短いターゲット文字列では、この効率の向上はごくわずかです。

1
ridgerunner

別の解決策:

import re

passwordRegex = re.compile(r'''(
    ^(?=.*[A-Z].*[A-Z])                # at least two capital letters
    (?=.*[!@#$&*])                     # at least one of these special c-er
    (?=.*[0-9].*[0-9])                 # at least two numeric digits
    (?=.*[a-z].*[a-z].*[a-z])          # at least three lower case letters
    .{8,}                              # at least 8 total digits
    $
    )''', re.VERBOSE)

def userInputPasswordCheck():
    print('Enter a potential password:')
    while True:
        m = input()
        mo = passwordRegex.search(m) 
        if (not mo):
           print('''
Your password should have at least one special charachter,
two digits, two uppercase and three lowercase charachter. Length: 8+ ch-ers.

Enter another password:''')          
        else:
           print('Password is strong')
           return
userInputPasswordCheck()
0
S.Sergey

PHPの場合、これは正常に機能します!

 if(preg_match("/^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^0-9]*[0-9]){2}).{8,}$/", 
 'CaSu4Li8')){
    return true;
 }else{
    return fasle;
 }

この場合、結果は真です

@ridgerunnerのタスク

0
Alejandro Peña
import re

RegexLength=re.compile(r'^\S{8,}$')
RegexDigit=re.compile(r'\d')
RegexLower=re.compile(r'[a-z]')
RegexUpper=re.compile(r'[A-Z]')


def IsStrongPW(password):
    if RegexLength.search(password) == None or RegexDigit.search(password) == None or RegexUpper.search(password) == None or RegexLower.search(password) == None:
        return False
    else:
        return True

while True:
    userpw=input("please input your passord to check: \n")
    if userpw == "exit":
        break
    else:
        print(IsStrongPW(userpw))
0
ivy qin

パスワードは、次の4つの複雑性ルールのうち少なくとも3つを満たす必要があります。

[少なくとも1つの大文字(A〜Z)、少なくとも1つの小文字(a〜z)、少なくとも1桁(0〜9)、少なくとも1つの特殊文字—スペースも特殊文字として扱うことを忘れないでください]

少なくとも10文字

最大128文字

連続する2文字を超えない(たとえば、111は許可されない)

'^(?!.(。)\ 1 {2})((?=。 [az])(?= .[AZ])(?=。 [0-9])|(?= .[az])(?=。 [AZ])(?= .[^ a-zA-Z0-9])| (?=。 [AZ])(?= .[0-9])(?=。 [^ a-zA-Z0-9])|(?= .-- [az])(?=。 [0-9])(?=。* [^ a-zA-Z0-9]))。{10,127} $ '

(?!。*(。)\ 1 {2})

(?= .[a-z])(?=。 [A-Z])(?=。* [0-9])

(?= .[a-z])(?=。 [A-Z])(?=。* [^ a-zA-Z0-9])

(?= .[A-Z])(?=。 [0-9])(?=。* [^ a-zA-Z0-9])

(?= .[a-z])(?=。 [0-9])(?=。* [^ a-zA-Z0-9])

。{10.127}

0
Ra Vi