Regexp Java para validação de senha

Estou criando um regexp para validação de senha a ser usado em um aplicativo Java como um parâmetro de configuração.

O regexp é:

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

A política de senha é:

Eu estou perdendo apenas o ponto 5. Eu não sou capaz de ter a verificação de espaço, guia, retorno de carro, etc.

Alguém pode ajudar-me?

Tente isto:

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

Explicação:

 ^ # start-of-string (?=.*[0-9]) # a digit must occur at least once (?=.*[az]) # a lower case letter must occur at least once (?=.*[AZ]) # 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 

É fácil adicionar, modificar ou remover regras individuais, uma vez que cada regra é um “módulo” independente.

A construção (?=.*[xyz]) come toda a cadeia ( .* ) E retrocede para a primeira ocorrência em que [xyz] pode corresponder. Se for encontrado [xyz] , ele falhará de outra forma.

A alternativa seria usar um qualificador relutante: (?=.*?[xyz]) . Para uma verificação de senha, isso dificilmente fará alguma diferença, pois, para seqüências muito mais longas, pode ser a variante mais eficiente.

A variante mais eficiente (mas mais difícil de ler e manter, portanto, mais propensa a erros) seria (?=[^xyz]*[xyz]) , é claro. Por uma regex desse tamanho e para esse propósito, eu recomendaria fazê-lo dessa maneira, já que não tem benefícios reais.

exemplo simples usando regex

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

Explicações:

  • (?=.*[0-9]) um dígito deve ocorrer pelo menos uma vez
  • (?=.*[az]) uma letra minúscula deve ocorrer pelo menos uma vez
  • (?=.*[AZ]) uma letra maiúscula deve ocorrer pelo menos uma vez
  • (?=.*[@#$%^&+=]) um caractere especial deve ocorrer pelo menos uma vez
  • (?=\\S+$) nenhum espaço em branco permitido em toda a string
  • .{8,} pelo menos 8 caracteres

Todas as respostas dadas anteriormente usam a mesma técnica (correta) para usar um lookahead separado para cada requisito. Mas eles contêm um par de ineficiências e um bug potencialmente enorme, dependendo do back-end que realmente vai usar a senha.

Vou começar com o regex da resposta aceita:

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

Em primeiro lugar, como o Java suporta \A e \z , prefiro usá-los para garantir que toda a cadeia seja validada, independentemente do Pattern.MULTILINE . Isso não afeta o desempenho, mas evita erros quando regexes são reciclados.

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

Verificar se a senha não contém espaço em branco e verificar seu comprimento mínimo pode ser feito em uma única passagem usando o conjunto de uma vez colocando o quantificador de variável {8,} no atalho \S que limita os caracteres permitidos:

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

Se a senha fornecida contiver um espaço, todas as verificações serão feitas, apenas para que a verificação final falhe no espaço. Isto pode ser evitado substituindo todos os pontos por \S :

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

O ponto só deve ser usado se você quiser permitir qualquer personagem. Caso contrário, use uma class de caractere (negada) para limitar seu regex somente aos caracteres realmente permitidos. Embora faça pouca diferença neste caso, não usar o ponto quando algo mais apropriado é um hábito muito bom. Eu vejo muitos casos de retrocesso catastrófico porque o desenvolvedor estava com preguiça de usar algo mais apropriado do que o ponto.

Como há uma boa chance de os testes iniciais encontrarem um caractere apropriado na primeira metade da senha, um quantificador lento pode ser mais eficiente:

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

Mas agora para a questão realmente importante: nenhuma das respostas menciona o fato de que a pergunta original parece ser escrita por alguém que pensa em ASCII. Mas em seqüências de caracteres Java são Unicode. Os caracteres não ASCII são permitidos em senhas? Se estiverem, são apenas espaços ASCII desaprovados ou todos os espaços em branco Unicode devem ser excluídos.

Por padrão, \s corresponde apenas ao espaço em branco ASCII, portanto, seu \S inverso corresponde a todos os caracteres Unicode (espaço em branco ou não) e a todos os caracteres ASCII que não são espaços em branco. Se caracteres Unicode forem permitidos, mas os espaços Unicode não forem, o sinalizador UNICODE_CHARACTER_CLASS poderá ser especificado para fazer \S excluir o espaço em branco Unicode. Se caracteres Unicode não forem permitidos, [\x21-\x7E] poderá ser usado em vez de \S para corresponder a todos os caracteres ASCII que não sejam um espaço ou um caractere de controle.

O que nos leva ao próximo problema em potencial: queremos permitir caracteres de controle? O primeiro passo para escrever um regex adequado é especificar exatamente o que você quer combinar e o que você não quer. A única resposta 100% tecnicamente correta é que a especificação da senha na pergunta é ambígua porque não indica se certos intervalos de caracteres como caracteres de controle ou não-ASCII são permitidos ou não.

Você não deve usar Regex excessivamente complexo (se puder evitá-los) porque eles são

  • difícil de ler (pelo menos para todos, menos para você)
  • difícil estender
  • difícil de depurar

Embora possa haver uma pequena sobrecarga de desempenho no uso de muitas pequenas expressões regulares, os pontos acima do outweight são mais fáceis.

Eu implementaria assim:

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

Requisito de senha:

  • A senha deve ter pelo menos oito (8) caracteres de comprimento onde o sistema possa suportá-la.
  • As senhas devem include caracteres de pelo menos dois (2) desses agrupamentos: caracteres alfa, numéricos e especiais.

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

Eu testei e funciona

Para qualquer pessoa interessada em requisitos mínimos para cada tipo de personagem, sugiro fazer a seguinte extensão sobre a resposta aceita por Tomalak:

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

Note que esta é uma string de formatação e não o padrão final de regex. Apenas substitua% d pelas ocorrências mínimas necessárias para: dígitos, minúsculas, maiúsculas, não dígitos / caractere e senha inteira (respectivamente). Ocorrências máximas são improváveis ​​(a menos que você queira um máximo de 0, efetivamente rejeitando quaisquer desses caracteres), mas elas podem ser facilmente adicionadas também. Observe o agrupamento extra em torno de cada tipo para que as restrições min / max permitam correspondências não consecutivas. Isso funcionou muito bem para um sistema em que pudéssemos configurar centralmente quantos tipos de caracteres solicitamos e, em seguida, ter o site e duas plataformas móveis diferentes para buscar essas informações, a fim de construir o padrão regex com base na string de formatação acima.

Eu acho que isso pode ser feito também (como um modo mais simples):

 ^(?=.*\d)(?=.*[az])(?=.*[AZ])(?=.*[@#$%^&+=])[^\s]{8,}$ 

[Regex Demo]

Facil

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

  1. (? = qualquer coisa) -> significa positivo olha para frente em todas as seqüências de caracteres de input e certifique-se de que esta condição seja escrita .amostra (? =. * [0-9]) -> significa que um número de dígito é escrito em toda a cadeia. se não for escrito, retorne falso .
  2. (?! qualquer coisa) -> (vise versa) significa olhares negativos para frente se a condição for escrita return false .

    significado próximo ^ (condição) (condição) (condição) (condição) [\ S] {8,10} $

 String s=pwd; int n=0; for(int i=0;iAccepted
"); } else { out.print("Password must be alphanumeric Declined
"); }

Explicação:

  1. Primeiro defina a senha como uma string e crie o conjunto inteiro o.
  2. Em seguida, verifique o char de cada um por loop.
  3. Se encontrar o número na string, então o n add 5. Em seguida, pule para o próximo loop for. Character.isDigit (s.charAt (i))
  4. Este loop verifica todos os alfabetos colocados na string. Se encontrar, adicione mais 5 em n. Character.isLetter (s.charAt (i))
  5. Agora verifique o inteiro n pela condição if. Se n = 10 for verdadeiro, uma string será alfanumérica, caso contrário, não.