development

암호 강도를 확인하는 정규식

big-blog 2020. 7. 2. 07:16
반응형

암호 강도를 확인하는 정규식


내 비밀번호 강도 기준은 다음과 같습니다.

  • 8 자 길이
  • 대문자 2 자
  • 1 특성 (!@#$&*)
  • 2 자리 (0-9)
  • 소문자 3 자

누군가 나에게 같은 정규식을 줄 수 있습니까? 모든 조건은 비밀번호로 충족해야합니다.


긍정적 인 미리보기 어설 션을 사용하여 이러한 검사를 수행 할 수 있습니다.

^(?=.*[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.

길이가 0 인 긍정적 인 예측을 사용하여 각 구속 조건을 개별적으로 지정할 수 있습니다.

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

지원하지 않는 정규식 엔진의 경우 \p표기하고 순수한 ASCII가 충분하다, 당신은 대체 할 수 \p{Lu}[A-Z]\p{Ll}함께 [a-z].


위의 답변은 완벽하지만 큰 정규 표현식 대신 여러 개의 작은 정규 표현식을 사용하는 것이 좋습니다 .
긴 정규 표현식을 분할하면 몇 가지 장점이 있습니다.

  • 읽고 쓰기 쉬움
  • 디버그하기 쉬움
  • 정규식의 일부를 추가 / 제거하기 쉬움

일반적으로이 접근 방식은 코드를 쉽게 유지 관리 할 수 ​​있도록 유지 합니다.

나는 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 []
        }
    }
}

나는 추가하는 것이 좋습니다

(?!.*pass|.*word|.*1234|.*qwer|.*asdf) exclude common passwords

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)

부정 된 문자 클래스는 한 번의 단계로 원하는 문자까지 모든 것을 소비하므로 역 추적이 필요 없습니다. (점 스타 솔루션은 잘 작동하지만 역 추적이 필요합니다.) 물론 암호와 같은 짧은 대상 문자열의 경우 이러한 효율성 향상은 무시할 수 있습니다.


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))

PHP의 경우 이것은 잘 작동합니다!

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

이 경우 결과는 사실입니다

@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()

비밀번호는 다음 4 가지 복잡성 규칙 중 3 가지 이상을 충족해야합니다.

[at least 1 uppercase character (A-Z) at least 1 lowercase character (a-z) at least 1 digit (0-9) at least 1 special character — do not forget to treat space as special characters too]

at least 10 characters

at most 128 characters

not more than 2 identical characters in a row (e.g., 111 not allowed)

'^(?!.(.)\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}$'

(?!.*(.)\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}

참고URL : https://stackoverflow.com/questions/5142103/regex-to-validate-password-strength

반응형