|
@@ -0,0 +1,155 @@
|
|
|
|
|
+package com.ctsi.utils;
|
|
|
|
|
+
|
|
|
|
|
+import org.apache.logging.log4j.util.Strings;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
+
|
|
|
|
|
+public class PasswordUtils {
|
|
|
|
|
+ public static Boolean isValidPassword;
|
|
|
|
|
+ public static String message;
|
|
|
|
|
+
|
|
|
|
|
+ public Boolean getIsValidPassword() {
|
|
|
|
|
+ return isValidPassword;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public String getMessage() {
|
|
|
|
|
+ return message;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //定义横向穷举
|
|
|
|
|
+ private static final String[][] KEY_CODE = {
|
|
|
|
|
+ {"`~·", "1!!", "2@@", "3#", "4$¥", "5%", "6^……", "7&", "8*", "9((", "0))", "-_", "=+"},
|
|
|
|
|
+ {" ","qQ", "wW", "eE", "rR", "tT", "yY", "uU", "iI", "oO", "pP", "[{【", "]}】", "\\|、"},
|
|
|
|
|
+ {" ","aA", "sS", "dD", "fF", "gG", "hH", "jJ", "kK", "lL", ";:", "\'\"’“"},
|
|
|
|
|
+ {" ","zZ", "xX", "cC", "vV", "bB", "nN", "mM", ",《<", ".>》", "/??"}
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ public PasswordUtils(Boolean isValid, String message1) {
|
|
|
|
|
+ isValidPassword = isValid;
|
|
|
|
|
+ message = message1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static PasswordUtils isValid(String password,String userName) {
|
|
|
|
|
+ // 密码长度至少8位
|
|
|
|
|
+ if (password.length() < 8) {
|
|
|
|
|
+ return new PasswordUtils(false, "密码最少8位");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 密码长度最多20位
|
|
|
|
|
+ if (password.length() > 20) {
|
|
|
|
|
+ return new PasswordUtils(false, "密码最多20位");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 密码必须包含英文和数字
|
|
|
|
|
+ Pattern pattern = Pattern.compile("^(?=.*[a-zA-Z])(?=.*\\d).+$");
|
|
|
|
|
+ Matcher matcher = pattern.matcher(password);
|
|
|
|
|
+ if (!matcher.matches()) {
|
|
|
|
|
+ return new PasswordUtils(false, "密码必须包含英文和数字");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 不允许使用连续的字符串密码
|
|
|
|
|
+ if (isSequential(password)) {
|
|
|
|
|
+ return new PasswordUtils(false, "密码不能使用连续字符");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 不允许使用连续的键盘密码
|
|
|
|
|
+ if (isKeyBoardContinuousChar(password)) {
|
|
|
|
|
+ return new PasswordUtils(false, "密码不能使用连续键盘字符");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 判断密码不能包含用户名
|
|
|
|
|
+ if (checkUserName(password, userName)) {
|
|
|
|
|
+ return new PasswordUtils(false, "密码不应包含用户名信息");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return new PasswordUtils(true, "");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static boolean isSequential(String password) {
|
|
|
|
|
+ String lowercase = password.toLowerCase();
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < lowercase.length() - 2; i++) {
|
|
|
|
|
+ char current = lowercase.charAt(i);
|
|
|
|
|
+ char next1 = (char) (current + 1);
|
|
|
|
|
+ char next2 = (char) (current + 2);
|
|
|
|
|
+
|
|
|
|
|
+ if (lowercase.charAt(i + 1) == next1 && lowercase.charAt(i + 2) == next2) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 是否包含3个及以上键盘连续字符
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param password 待匹配的字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ private static boolean isKeyBoardContinuousChar(String password) {
|
|
|
|
|
+ if (Strings.isBlank(password)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ //找出给出的字符串,每个字符,在坐标系中的位置。
|
|
|
|
|
+ char[] c = password.toCharArray();
|
|
|
|
|
+ List<Integer> x = new ArrayList<Integer>();
|
|
|
|
|
+ List<Integer> y = new ArrayList<Integer>();
|
|
|
|
|
+ for (char temp : c) {
|
|
|
|
|
+ toHere:
|
|
|
|
|
+ for (int j = 0; j < KEY_CODE.length; j++) {
|
|
|
|
|
+ for (int k = 0; k < KEY_CODE[j].length; k++) {
|
|
|
|
|
+ String jk = KEY_CODE[j][k];
|
|
|
|
|
+ if (jk.contains(String.valueOf(temp))) {
|
|
|
|
|
+ x.add(j);
|
|
|
|
|
+ y.add(k);
|
|
|
|
|
+ break toHere;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ boolean flag = false;
|
|
|
|
|
+ for (int i = 0; i < x.size() - 3; i++) {
|
|
|
|
|
+ // 如果X一致,那么就是在一排
|
|
|
|
|
+ //四者在同一行上
|
|
|
|
|
+ if (x.get(i) .equals(x.get(i + 1)) && x.get(i + 1).equals(x.get(i + 2))
|
|
|
|
|
+ && x.get(i + 2).equals(x.get(i + 3))) {
|
|
|
|
|
+ if (y.get(i) > y.get(i + 3)) {
|
|
|
|
|
+ if (y.get(i) - 1 == y.get(i + 1) && y.get(i) - 2 == y.get(i + 2) && y.get(i) - 3 == y.get(i + 3)) {
|
|
|
|
|
+ flag = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (y.get(i) + 1 == y.get(i + 1) && y.get(i) + 2 == y.get(i + 2) && y.get(i) + 3 == y.get(i + 3)) {
|
|
|
|
|
+ flag = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else if (!x.get(i).equals(x.get(i + 1))
|
|
|
|
|
+ && !x.get(i + 1).equals( x.get(i + 2))
|
|
|
|
|
+ && !x.get(i).equals(x.get(i + 2))
|
|
|
|
|
+ && !x.get(i).equals(x.get(i + 3))
|
|
|
|
|
+ && !x.get(i + 1).equals(x.get(i + 3))
|
|
|
|
|
+ && !x.get(i + 2).equals(x.get(i + 3))){
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //四者均不在同一行上,但是如果y相同,说明是一列
|
|
|
|
|
+ if (y.get(i).equals(y.get(i + 1)) && y.get(i + 1).equals(y.get(i + 2))
|
|
|
|
|
+ && y.get(i+ 2).equals(y.get(i + 3)) ) {
|
|
|
|
|
+ flag = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (y.get(i).equals(y.get(i + 1)+1) && y.get(i + 1).equals(y.get(i + 2)+1)
|
|
|
|
|
+ && y.get(i+ 2).equals(y.get(i + 3)+1) ) {
|
|
|
|
|
+ flag = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ return flag;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static Boolean checkUserName(String password, String userName){
|
|
|
|
|
+ return password.toLowerCase().contains(userName.toLowerCase());
|
|
|
|
|
+ }
|
|
|
|
|
+}
|