2010-09-27 73 views
73

Estoy creando una expresión regular para la validación de contraseña que se utilizará en una aplicación Java como parámetro de configuración.Regexp Java para la validación de contraseña

La expresión regular es:

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

La directiva de contraseñas es:

  • Al menos 8 caracteres

  • contiene al menos un dígito

  • contiene al menos una char inferior alfa y un char alfa superior

  • contiene al menos un carbón dentro de un conjunto de caracteres especiales (@#%$^ etc.)

  • No contiene espacios, tabulaciones, etc.

me falta solo punto 5. No puedo tener la comprobación de expresiones regulares para espacio, pestaña, retorno de carro, etc.

¿Alguien podría ayudarme?

+0

Normas para las contraseñas son malos. Consulte [Referencia - Validación de contraseña] (https://stackoverflow.com/questions/48345922/reference-password-validation) para obtener más información. – ctwheels

Respuesta

201

Prueba esto:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$ 

Explicación:

^     # start-of-string 
(?=.*[0-9])  # a digit must occur at least once 
(?=.*[a-z])  # a lower case letter must occur at least once 
(?=.*[A-Z])  # an upper case letter must occur at least once 
(?=.*[@#$%^&+=]) # a special character must occur at least once 
(?=\S+$)   # no whitespace allowed in the entire string 
.{8,}    # anything, at least eight places though 
$     # end-of-string 

Es fácil de añadir, modificar o eliminar reglas individuales, ya que cada regla es un "módulo" independiente.

El (?=.*[xyz]) constructo come la cadena completa (.*) y se echa para atrás a la primera ocurrencia donde [xyz] pueden igualar. Tiene éxito si se encuentra [xyz], de lo contrario falla.

La alternativa sería usar un calificador reacio: (?=.*?[xyz]). Para una verificación de contraseña, esto no hará ninguna diferencia, para cadenas mucho más largas podría ser la variante más eficiente.

La variante más eficiente (pero la más difícil de leer y mantener, por lo tanto, la más propensa a errores) sería (?=[^xyz]*[xyz]), por supuesto. Para una expresión regular de esta longitud y para este propósito, recomendaría hacerlo de esa manera, ya que no tiene ningún beneficio real.

+11

@ Kerby82: en cadenas de Java, las barras invertidas deben escaparse. Intenta usar '\\ s'. Ese es un requisito de Java, no un requisito de expresiones regulares. – Tomalak

+0

yes \ t no tiene sentido porque \ s incluye Un carácter de espacio en blanco: [\ t \ n \ x0B \ f \ r]. Pero retroceder el \ s ahora en Java funciona perfectamente. ¡Muchas gracias! – Kerby82

+0

Puede desactivar el modo multilínea explícitamente como parte de la expresión regular si lo necesita al usar (? -m: ...) en todo lo demás –

33

sencillo ejemplo usando expresiones regulares

public class passwordvalidation { 
    public static void main(String[] args) { 
     String passwd = "[email protected]"; 
     String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}"; 
     System.out.println(passwd.matches(pattern)); 
    } 
} 

Explicaciones:

  • (?=.*[0-9]) debe ocurrir un dígito al menos una vez
  • (?=.*[a-z]) una letra minúscula debe ocurrir al menos una vez
  • (?=.*[A-Z]) una parte superior la carta de caso debe aparecer al menos una vez
  • (?=.*[@#$%^&+=]) un carácter especial debe ocurrir al menos una vez
  • (?=\\S+$) sin espacios en blanco permitida en toda la cadena de
  • .{8,} al menos 8 caracteres
+3

. {5,10} representa un mínimo de 5 caracteres y un máximo de 10 caracteres. Por si acaso alguien está buscando una explicación específica. – iabhi

+0

@iabhi, estaba buscando esto. Gracias. –

1

contraseña Requisito:

  • contraseña debe ser de al menos ocho (8) caracteres de longitud donde el sistema puede soportarlo.
  • Las contraseñas deben incluir caracteres de al menos dos (2) de estas agrupaciones: alfa, numérico y caracteres especiales.

    ^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[[email protected]#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[[email protected]#$%^&]).*$ 
    

lo probé y funciona

0

Creo que esto puede hacerlo también (como un modo más simple):

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$ 

[Regex Demo]

9

Todo lo dado previamente las respuestas usan la misma técnica (correcta) para usar una búsqueda anticipada separada para cada requisito. Pero contienen un par de ineficiencias y un error potencialmente masivo, dependiendo de la parte de atrás que usará la contraseña.

Voy a empezar con la expresión regular de la respuesta aceptada:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$ 

En primer lugar, ya que es compatible con Java \A y \z Yo prefiero usar los para asegurarse de que toda la cadena se valida, independientemente Pattern.MULTILINE . Esto no afecta el rendimiento, pero evita errores cuando las expresiones regulares se reciclan.

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z 

Comprobación de que la contraseña no contiene espacios en blanco y comprobar su longitud mínima se puede hacer en un solo paso utilizando el todo a la vez, poniendo cuantificador variable de {8,} en la taquigrafía \S que limita los caracteres permitidos:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z 

Si la contraseña proporcionada contiene un espacio, se realizarán todas las comprobaciones, solo para que la verificación final falle en el espacio.Esto se puede evitar mediante la sustitución de todos los puntos con \S:

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z 

El punto sólo debe utilizarse si realmente desea permitir que cualquier carácter. De lo contrario, use una clase de caracteres (negada) para limitar su expresión regular solo a aquellos caracteres que realmente están permitidos. Aunque hace poca diferencia en este caso, not using the dot when something else is more appropriate es un muy buen hábito. Veo demasiados casos de catastrophic backtracking porque el desarrollador era demasiado perezoso para usar algo más apropiado que el punto.

Dado que hay una buena probabilidad de las pruebas iniciales encontrarán un carácter apropiado en la primera mitad de la contraseña, un cuantificador perezoso puede ser más eficiente:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z 

Pero ahora para el problema realmente importante: ninguno de las respuestas mencionan el hecho de que la pregunta original parece escrita por alguien que piensa en ASCII. Pero en Java las cadenas son Unicode. ¿Se permiten caracteres no ASCII en las contraseñas? Si lo son, solo se inhabilitan los espacios ASCII o se deben excluir todos los espacios en blanco Unicode.

De forma predeterminada, \s solo coincide con espacios en blanco ASCII, por lo que su inversa \S coincide con todos los caracteres Unicode (espacios en blanco o no) y todos los caracteres ASCII que no sean espacios en blanco. Si se permiten caracteres Unicode pero los espacios Unicode no lo están, se puede especificar el indicador UNICODE_CHARACTER_CLASS para hacer que \S excluya el espacio en blanco Unicode. Si los caracteres Unicode no están permitidos, entonces se puede usar [\x21-\x7E] en lugar de \S para que coincida con todos los caracteres ASCII que no sean un espacio o un carácter de control.

Lo que nos lleva al próximo problema potencial: ¿queremos permitir caracteres de control? El primer paso para escribir una expresión regular adecuada es especificar exactamente lo que quiere que coincida y lo que no. La única respuesta 100% técnicamente correcta es que la especificación de la contraseña en la pregunta es ambigua porque no indica si ciertos rangos de caracteres como los caracteres de control o los caracteres no ASCII están permitidos o no.

3

Usted no debe usar expresiones regulares demasiado complejo (si se puede evitar ellos) porque son

  • difícil de leer (al menos para todos, pero usted mismo)
  • difícil de extender
  • difíciles de depurar

Aunque puede haber una pequeña sobrecarga de rendimiento en el uso de muchas expresiones regulares pequeñas, los puntos anteriores lo superan fácilmente.

Me gustaría poner en práctica la siguiente manera:

bool matchesPolicy(pwd) { 
    if (pwd.length < 8) return false; 
    if (not pwd =~ /[0-9]/) return false; 
    if (not pwd =~ /[a-z]/) return false; 
    if (not pwd =~ /[A-Z]/) return false; 
    if (not pwd =~ /[%@$^]/) return false; 
    if (pwd =~ /\s/) return false; 
    return true; 
} 
+0

Y desde una perspectiva de seguridad, es mucho mejor forzar contraseñas más largas, evitar las contraseñas bien conocidas (como 12345 y pasar = usuario) en lugar de hacer que las contraseñas sean muy complicadas y difíciles de recordar. –

0

Para todos los interesados ​​en los requerimientos mínimos para cada tipo de personaje, sugeriría hacer la siguiente extensión sobre respuesta aceptada de Tomalak:

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$ 

en cuenta que una esta es una cadena de formato y no el patrón de expresión regular final. Simplemente sustituya% d con las ocurrencias mínimas requeridas para: dígitos, minúsculas, mayúsculas, no dígitos/caracteres y contraseña completa (respectivamente). Las instancias máximas son poco probables (a menos que desee un máximo de 0, rechazando efectivamente dichos caracteres) pero también podrían agregarse fácilmente. Observe la agrupación adicional alrededor de cada tipo para que las restricciones mínima/máxima permitan coincidencias no consecutivas.Esto funcionó de maravillas para un sistema en el que podíamos configurar de manera centralizada cuántos de cada tipo de personaje necesitábamos y luego hacer que el sitio web y dos plataformas móviles diferentes obtuvieran esa información para construir el patrón de expresiones regulares basado en la cadena de formato anterior.

0

fácil una

("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8,10} $ ")

  1. (= nada) -> significa positivo mira hacia adelante en toda la cadena de entrada y asegúrese de que para esta condición se .sample escrito (=? . * [0-9]) -> significa que se debe escribir un número de un dígito en toda la cadena. Si no está escrito return falso .
  2. (nada?!) -> (viceversa) significa negativo espera si la condición es escrito retorno falsa.

    cerca significado^(condición) (condición) (condición) (condición) [\ S] {8,10} $

+0

Si bien las respuestas con solo el código pueden proporcionar una solución al problema, algunas explicaciones mejorarían en gran medida la calidad de la respuesta. –

Cuestiones relacionadas