Regex для проверки надежности пароля.
Мои критерии прочности пароля следующие:
- длина 8 символов
- 2 буквы в верхнем случае
- 1 Специальный символ
([email protected]#$&*)
- 2 цифры
(0-9)
- 3 буквы в нижнем случае
Может кто-нибудь, пожалуйста, дайте мне регулярное выражение для этого. Все условия должны быть выполнены с помощью пароля.
Ответы
Ответ 1
Вы можете выполнить эти проверки, используя положительные ожидания вперед:
^(?=.*[A-Z].*[A-Z])(?=.*[[email protected]#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
Рублевая ссылка
Пояснение:
^ Start anchor
(?=.*[A-Z].*[A-Z]) Ensure string has two uppercase letters.
(?=.*[[email protected]#$&*]) 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.
Ответ 2
Вы можете использовать позитивный внешний вид с нулевой длиной, чтобы указать каждое из ваших ограничений отдельно:
(?=.{8,})(?=.*\p{Lu}.*\p{Lu})(?=.*[[email protected]#$&*])(?=.*[0-9])(?=.*\p{Ll}.*\p{Ll})
Если ваш механизм регулярных выражений не поддерживает обозначение \p
, а чистый ASCII достаточно, вы можете заменить \p{Lu}
на [A-Z]
и \p{Ll}
на [A-Z]
.
Ответ 3
Ответы, приведенные выше, являются совершенными, но я предлагаю использовать несколько меньших регулярных выражений, а не большой.
Разделение длинного регулярного выражения имеет некоторые преимущества:
- легкость писать и читать
- легкость отладки
- легкость добавления/удаления части регулярного выражения
Как правило, этот подход сохраняет код легко поддерживаемым.
Сказав это, я разделяю фрагмент кода, который я пишу в 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 []
}
}
}
Ответ 4
Я бы предложил добавить
(?!.*pass|.*word|.*1234|.*qwer|.*asdf) exclude common passwords
Ответ 5
Решение 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.
(?=[^[email protected]#$&*]*[[email protected]#$&*]) # 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)
Отрицательные классы символов потребляют все до желаемого символа за один шаг, требуя нулевого обратного отсчета. (Решение с точкой-точкой работает очень хорошо, но требует некоторого возврата). Конечно, с короткими целевыми строками, такими как пароли, это повышение эффективности будет незначительным.
Ответ 6
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))
Ответ 7
Для PHP это работает отлично!
if(preg_match("/^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^0-9]*[0-9]){2}).{8,}$/",
'CaSu4Li8')){
return true;
}else{
return fasle;
}
в этом случае результат верен
Спасибо за @ridgerunner
Ответ 8
Другое решение:
import re
passwordRegex = re.compile(r'''(
^(?=.*[A-Z].*[A-Z]) # at least two capital letters
(?=.*[[email protected]#$&*]) # 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()
Ответ 9
Пароль должен соответствовать как минимум 3 из следующих 4 правил сложности,
[хотя бы 1 заглавная буква (AZ) не менее 1 строчная буква (az) не менее 1 цифры (0-9) не менее 1 специального символа - не забывайте также рассматривать пробел как специальные символы]
не менее 10 символов
максимум 128 символов
не более 2 одинаковых символов подряд (например, 111 не допускается)
'^ (?!. (.)\1 {2}) ((? =. [Az]) (? =. [AZ]) (? =. [0-9]) | (? =. [Az] ) (= [AZ]) (= [^ A-Za-Z0-9]) |?.?.?.?.?. (= [AZ]) (= [0-9]) (= [^ а -zA-Z0-9]) |?. (= [AZ]) (= [0-9]) (= * [^ A-Za-Z0-9])) {10127} $?.?..
(?!. * (.)\1 {2})
(? =. [AZ]) (? =. [AZ]) (? =. * [0-9])
(? =. [AZ]) (? =. [AZ]) (? =. * [^ А-Za-z0-9])
(? =. [AZ]) (? =. [0-9]) (? =. * [^ А-Za-z0-9])
(? =. [AZ]) (? =. [0-9]) (? =. * [^ А-Za-z0-9])
. {10,127}