암호 유효성 검사를위한 Regexp Java
Java 응용 프로그램에서 구성 매개 변수로 사용할 암호 유효성 검사를위한 정규 표현식을 만들고 있습니다.
정규식은 다음과 같습니다.
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
비밀번호 정책은 다음과 같습니다.
8 자 이상
하나 이상의 숫자를 포함합니다.
하나 이상의 하위 알파 문자와 하나의 상위 알파 문자를 포함합니다.
특수 문자 집합 (
@#%$^
등) 내에 하나 이상의 문자를 포함합니다 .공백, 탭 등을 포함하지 않습니다.
포인트 5 만 누락되었습니다. 정규 표현식에서 공백, 탭, 캐리지 리턴 등을 확인할 수 없습니다.
누구든지 나를 도울 수 있습니까?
이 시도:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
설명:
^ # 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
모든 규칙이 독립적 인 "모듈"이기 때문에 개별 규칙을 쉽게 추가, 수정 또는 제거 할 수 있습니다.
(?=.*[xyz])
구조체 전체 문자열 (먹는다 .*
최초로 출현하는) 및 역 추적 [xyz]
일치시킬 수있다. [xyz]
발견되면 성공하고 그렇지 않으면 실패합니다.
대안은 꺼리는 한정자를 사용하는 것입니다 : (?=.*?[xyz])
. 암호 확인의 경우에는 거의 차이가 없으며 훨씬 긴 문자열의 경우 더 효율적인 변형이 될 수 있습니다.
가장 효율적인 변형 (그러나 읽기 및 유지 관리가 가장 어렵 기 때문에 오류 발생 가능성이 가장 높음)은 (?=[^xyz]*[xyz])
물론입니다. 이 길이의 정규식과 이러한 목적의 경우 실제 이점이 없기 때문에 그렇게하는 것을 권장하지 않습니다.
정규식을 사용한 간단한 예
public class passwordvalidation {
public static void main(String[] args) {
String passwd = "aaZZa44@";
String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
System.out.println(passwd.matches(pattern));
}
}
설명 :
(?=.*[0-9])
숫자는 한 번 이상 있어야합니다.(?=.*[a-z])
소문자는 한 번 이상 있어야합니다.(?=.*[A-Z])
대문자는 한 번 이상 있어야합니다.(?=.*[@#$%^&+=])
특수 문자는 한 번 이상 나타나야합니다.(?=\\S+$)
전체 문자열에 공백이 허용되지 않습니다..{8,}
8 자 이상
이전에 제공된 모든 답변은 동일한 (올바른) 기술을 사용하여 각 요구 사항에 대해 별도의 미리보기를 사용합니다. 그러나 실제로 암호를 사용할 백엔드에 따라 몇 가지 비효율 성과 잠재적으로 대규모 버그가 있습니다.
수락 된 답변에서 정규식으로 시작하겠습니다.
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
우선, Java 는 .NET과 독립적으로 전체 문자열의 유효성을 검사하기 위해 Java를 지원 \A
하고 \z
이를 사용하는 것을 선호하기 때문에 Pattern.MULTILINE
. 이것은 성능에 영향을 미치지 않지만 정규식이 재활용 될 때 실수를 방지합니다.
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z
암호에 공백이 포함되어 있지 않은지 확인하고 허용되는 문자를 제한하는 {8,}
속기 변수 수량 \S
자를 한 번에 사용하여 단일 패스로 최소 길이를 확인할 수 있습니다 .
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z
제공된 암호에 공백이 포함되어 있으면 모든 검사가 수행되고 해당 공백에 대한 최종 검사가 실패하게됩니다. 모든 점을 \S
다음 으로 바꾸면이를 방지 할 수 있습니다 .
\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z
점은 실제로 어떤 문자를 허용하려는 경우에만 사용해야합니다. 그렇지 않으면 (부정 된) 문자 클래스를 사용하여 정규식을 실제로 허용되는 문자로만 제한하십시오. 이 경우에는 별 차이가 없지만 다른 것이 더 적절할 때 점을 사용하지 않는 것은 아주 좋은 습관입니다. 개발자가 점보다 더 적절한 것을 사용하기에는 너무 게으 르기 때문에 엄청난 역 추적 사례가 너무 많습니다 .
초기 테스트에서 암호의 전반부에서 적절한 문자를 찾을 가능성이 높기 때문에 lazy quantifier가 더 효율적일 수 있습니다.
\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z
그러나 이제 정말 중요한 문제에 대해 설명합니다. 원래 질문이 ASCII로 생각하는 사람이 작성한 것처럼 보인다는 사실에 대한 답변은 없습니다. 그러나 Java에서 문자열은 유니 코드입니다. 비 ASCII 문자가 비밀번호에 허용됩니까? 그렇다면 ASCII 공백 만 허용되지 않거나 모든 유니 코드 공백을 제외해야합니다.
기본적으로 \s
ASCII 공백 만 일치하므로 그 역 \S
은 모든 유니 코드 문자 (공백 여부) 및 모든 비 공백 ASCII 문자와 일치합니다. 유니 코드 문자는 허용되지만 유니 코드 공백은 허용되지 않는 경우 유니 코드 공백 UNICODE_CHARACTER_CLASS
을 \S
제외 하도록 플래그를 지정할 수 있습니다 . 유니 코드 문자가 허용 되지 않으면 공백이나 제어 문자가 아닌 모든 ASCII 문자를 일치시키는 [\x21-\x7E]
대신 사용할 수 있습니다 \S
.
Which brings us to the next potential issue: do we want to allow control characters? The first step in writing a proper regex is to exactly specify what you want to match and what you don't. The only 100% technically correct answer is that the password specification in the question is ambiguous because it does not state whether certain ranges of characters like control characters or non-ASCII characters are permitted or not.
You should not use overly complex Regex (if you can avoid them) because they are
- hard to read (at least for everyone but yourself)
- hard to extend
- hard to debug
Although there might be a small performance overhead in using many small regular expressions, the points above outweight it easily.
I would implement like this:
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;
}
Password Requirement :
- Password should be at least eight (8) characters in length where the system can support it.
Passwords must include characters from at least two (2) of these groupings: alpha, numeric, and special characters.
^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$
I tested it and it works
For anyone interested in minimum requirements for each type of character, I would suggest making the following extension over Tomalak's accepted answer:
^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$
Notice that this is a formatting string and not the final regex pattern. Just substitute %d with the minimum required occurrences for: digits, lowercase, uppercase, non-digit/character, and entire password (respectively). Maximum occurrences are unlikely (unless you want a max of 0, effectively rejecting any such characters) but those could be easily added as well. Notice the extra grouping around each type so that the min/max constraints allow for non-consecutive matches. This worked wonders for a system where we could centrally configure how many of each type of character we required and then have the website as well as two different mobile platforms fetch that information in order to construct the regex pattern based on the above formatting string.
This one checks for every special character :
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\S+$).*[A-Za-z0-9].{8,}$
Java Method ready for you, with parameters
Just copy and paste and set your desired parameters.
If you don't want a module, just comment it or add an "if" as done by me for special char
//______________________________________________________________________________
/**
* Validation Password */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg) {
boolean result = false;
try {
if (PASSWORD_Arg!=null) {
//_________________________
//Parameteres
final String MIN_LENGHT="8";
final String MAX_LENGHT="20";
final boolean SPECIAL_CHAR_NEEDED=true;
//_________________________
//Modules
final String ONE_DIGIT = "(?=.*[0-9])"; //(?=.*[0-9]) a digit must occur at least once
final String LOWER_CASE = "(?=.*[a-z])"; //(?=.*[a-z]) a lower case letter must occur at least once
final String UPPER_CASE = "(?=.*[A-Z])"; //(?=.*[A-Z]) an upper case letter must occur at least once
final String NO_SPACE = "(?=\\S+$)"; //(?=\\S+$) no whitespace allowed in the entire string
//final String MIN_CHAR = ".{" + MIN_LENGHT + ",}"; //.{8,} at least 8 characters
final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}"; //.{5,10} represents minimum of 5 characters and maximum of 10 characters
final String SPECIAL_CHAR;
if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[@#$%^&+=])"; //(?=.*[@#$%^&+=]) a special character must occur at least once
else SPECIAL_CHAR="";
//_________________________
//Pattern
//String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
//_________________________
result = PASSWORD_Arg.matches(PATTERN);
//_________________________
}
} catch (Exception ex) {
result=false;
}
return result;
}
I think this can do it also (as a simpler mode):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$
easy one
("^ (?=.* [0-9]) (?=.* [a-z]) (?=.* [A-Z]) (?=.* [\\W_])[\\S]{8,10}$")
- (?= anything ) ->means positive looks forward in all input string and make sure for this condition is written .sample(?=.*[0-9])-> means ensure one digit number is written in the all string.if not written return false .
(?! anything ) ->(vise versa) means negative looks forward if condition is written return false.
close meaning ^(condition)(condition)(condition)(condition)[\S]{8,10}$
String s=pwd;
int n=0;
for(int i=0;i<s.length();i++)
{
if((Character.isDigit(s.charAt(i))))
{
n=5;
break;
}
else
{
}
}
for(int i=0;i<s.length();i++)
{
if((Character.isLetter(s.charAt(i))))
{
n+=5;
break;
}
else
{
}
}
if(n==10)
{
out.print("Password format correct <b>Accepted</b><br>");
}
else
{
out.print("Password must be alphanumeric <b>Declined</b><br>");
}
Explanation:
- First set the password as a string and create integer set o.
- Then check the each and every char by for loop.
- If it finds number in the string then the n add 5. Then jump to the next for loop. Character.isDigit(s.charAt(i))
- This loop check any alphabets placed in the string. If its find then add one more 5 in n. Character.isLetter(s.charAt(i))
- Now check the integer n by the way of if condition. If n=10 is true given string is alphanumeric else its not.
Also You Can Do like This.
public boolean isPasswordValid(String password) {
String regExpn =
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$";
CharSequence inputStr = password;
Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches())
return true;
else
return false;
}
참고URL : https://stackoverflow.com/questions/3802192/regexp-java-for-password-validation
'Programming' 카테고리의 다른 글
findAll Doctrine의 방법을 정렬하는 방법 (0) | 2020.08.19 |
---|---|
파이썬 열거 형 클래스에서 모든 값을 얻는 방법은 무엇입니까? (0) | 2020.08.19 |
android : 피카소로 원형 이미지 만들기 (0) | 2020.08.19 |
vi 편집기에서 문자열 검색 및 개수 가져 오기 (0) | 2020.08.19 |
지정된 형식 멤버 'Date'는 LINQ to Entities Exception에서 지원되지 않습니다. (0) | 2020.08.19 |