密码要求
// static char[] pwdSymbols = {'!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`','{','|','}','~'};
static final char[] pwdSymbols = {'!','#','$','%','&','(',')','*','+','-',':',';','<','=','>','?','@','[',']','^','_','{','|','}','~'};
static final char[] letters = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
static final char[] numbers = {'0','1','2','3','4','5','6','7','8','9'};
/**
* 1.密码不能包含账号信息
* 2.密码至少包含字母、数字、特殊符号中任意两种
* 3.不能出现连续3位以上的字母、数字和符号
* 4.密码最少8位长度
* @param account
* @return
*/
public static String newPwd(String account) {
return newPwd(account, 3, 8, 10);
}
/**
* 根据账号生成随机密码
* @param account 账号
* @param itemLen 相同字符连续时的最大长度
* @param pwdLenMin 生成密码的最小位数
* @param pwdLenMax 生成密码的最多位数
* @return
*/
public static String newPwd(String account, int itemLen, int pwdLenMin, int pwdLenMax) {
String[] accountItems = toAccountItems(account);
Random random = new Random();
int pwdLen = pwdLenMin+random.nextInt(pwdLenMax - pwdLenMin);
itemLen = itemLen < 3 ? 3 : itemLen;
StringBuilder pwdBuilder = new StringBuilder();
// 字符类型
int type = 1;
do {
int len = random.nextInt(100);
len = len%itemLen;
char[] pwdChars = makeChars(type, len+1, random);
pwdBuilder.append(pwdChars);
if (isContains(pwdBuilder, accountItems)) {
pwdBuilder.delete(pwdBuilder.length() - pwdChars.length, pwdBuilder.length());
continue;
}
// 修改include
if (len == type) {
len += 1;
if (len >= itemLen) {
len = 0;
}
}
type = len;
}while (pwdBuilder.length() < pwdLen);
return pwdBuilder.toString();
}
/**
* 判断密码中是否包含有账号信息
* @param pwdBuilder
* @param accountItems
* @return
*/
private static boolean isContains(StringBuilder pwdBuilder, String[] accountItems) {
String pwd = pwdBuilder.toString();
for (String accountItem : accountItems) {
if (pwd.endsWith(accountItem)) {
return true;
}
}
return false;
}
/**
* 分解账号
* 分解成子串数组,用来判断密码是否疑似包含有账号信息
* @param account
* @return
*/
private static String[] toAccountItems(String account) {
if (account.length() <= 4) {
return new String[]{account};
}
char[] chars = account.toCharArray();
int si = chars.length * 4 / 5;
List<String> items = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= chars.length-si; i++) {
sb.delete(0, sb.length());
for (int ii = i; ii < i+si; ii++) {
sb.append(chars[ii]);
}
items.add(sb.toString());
for (int j = si+i; j < chars.length; j++) {
sb.append(chars[j]);
items.add(sb.toString());
}
}
return ArrayUtil.toArray(items, String.class);
}
/**
* 随机生成指定长度的连续相同类型字符数组
* @param type
* @param len
* @param random
* @return
*/
private static char[] makeChars(int type, int len, Random random) {
char[] chars = letters;
switch (type) {
case 0:
chars = pwdSymbols;
break;
case 1:
chars = letters;
break;
default:
chars = numbers;
break;
}
char[] result = new char[len];
for (int i = 0; i < len; i++) {
int j = random.nextInt(chars.length);
result[i] = chars[j];
}
return result;
}
```