Regex para validar la fuerza de la contraseña

Mi criterio de fortaleza de la contraseña es el siguiente:

  • 8 caracteres de longitud
  • 2 letras en mayúscula
  • 1 carácter especial (!@#$&*)
  • 2 numerales (0-9)
  • 3 letras en minúsculas

¿Alguien puede darme expresiones regulares por lo mismo? Todas las condiciones se deben cumplir con una contraseña.

Puede hacer estos controles utilizando afirmaciones de aspecto positivo:

 ^(?=.*[AZ].*[AZ])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[az].*[az].*[az]).{8}$ 

Enlace Rubular

Explicación:

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

Puede usar look-aheads positivos de longitud cero para especificar cada una de sus restricciones por separado:

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

Si su motor regex no admite la notación \p y ASCII puro es suficiente, puede reemplazar \p{Lu} con [AZ] y \p{Ll} con [az] .

Las respuestas dadas anteriormente son perfectas, pero sugiero usar varias expresiones regulares más pequeñas en lugar de grandes.
La división de la expresión regular larga tiene algunas ventajas:

  • facilidad para escribir y leer
  • facilidad para depurar
  • facilidad para agregar / eliminar parte de la expresión regular

En general, este enfoque mantiene el código fácilmente mantenible .

Habiendo dicho eso, comparto un fragmento de código que escribo en Swift como ejemplo:

 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("[AZ]", text: password).count > 0 if !hasUpperCase { return false } let hasLowerCase = RegExp.matchesForRegexInText("[az]", 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 [] } } } 

Sugeriría agregar

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

La solución de codaddict funciona bien, pero esta es un poco más eficiente: (syntax de 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. (?=(?:[^AZ]*[AZ]){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) 

Las clases de caracteres negadas consumen todo hasta el carácter deseado en un solo paso, requiriendo cero retroceso. (La solución de punto estrella funciona bien, pero requiere algo de retroceso). Por supuesto, con cadenas de destino cortas como contraseñas, esta mejora de la eficiencia será insignificante.

 import re RegexLength=re.compile(r'^\S{8,}$') RegexDigit=re.compile(r'\d') RegexLower=re.compile(r'[az]') RegexUpper=re.compile(r'[AZ]') 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)) 

Para PHP, ¡esto funciona bien!

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

en este caso, el resultado es verdadero

Thsks para @ridgerunner

Otra solución:

 import re passwordRegex = re.compile(r'''( ^(?=.*[AZ].*[AZ]) # at least two capital letters (?=.*[!@#$&*]) # at least one of these special c-er (?=.*[0-9].*[0-9]) # at least two numeric digits (?=.*[az].*[az].*[az]) # 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() 

La contraseña debe cumplir al menos 3 de las siguientes 4 reglas de complejidad,

[al menos 1 carácter en mayúscula (AZ) al menos 1 carácter en minúscula (az) al menos 1 dígito (0-9) al menos 1 carácter especial – no se olvide de tratar el espacio como caracteres especiales también]

al menos 10 caracteres

a lo sumo 128 caracteres

no más de 2 caracteres idénticos en una fila (p. ej., 111 no permitido)

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

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