密码生成器,可选择密码长度,密码包含的字符,特殊字符,可排除字符等
生成效率高,生成后黏贴就能用(生成后直接回复制到剪贴板)
/**
* 密码生成器,如果选择包含某种类型字符,则至少含有一个该类型的字符,如选择含有大写字母,则至少含有一个大写字母
* @param excludeLetters 需要排除的字符, 包含大写 小写 数字 和特殊字符
* @param containNums 是否包含数字
* @param containUpperCase 是否包含大写字母
* @param containLowerCase 是否包含小写字母
* @param passwordLength 生成的密码长度
* @param howMany 生成多少个
* @param specialChar 密码中包含的特殊字符集
*/
private static void generatePassword(String excludeLetters,boolean containNums,boolean containUpperCase,
boolean containLowerCase,boolean containSpecSymbol,int passwordLength,int howMany,String specialChar){
// 记录程序开始时间,用于后面计算程序运行时长
long startTime = System.currentTimeMillis();
// 默认大小写字母和数字以及特殊字符
String nums = "1234567890";
String uppercaseLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String lowerCaseLetters = "abcdefghijklmnopqrstuvwxyz";
//特殊字符集 0OoB81lI"#$%&'()+,-./:;<=>?[\]_`{|}~!@^*
String specialSymbol = specialChar;
//将排除的字符从默认字符中去除 形成新的索引字符串
char[] arr;
StringBuilder builder = new StringBuilder();
StringBuilder allStringBuilder = new StringBuilder();
// 从数字冲排除字符,形成新的索引字符串
if(containNums) {
arr = nums.toCharArray();
for (char sch : arr) {
if (excludeLetters.indexOf(sch) != -1)
continue;
builder.append(sch);
}
nums = builder.toString();
allStringBuilder.append(nums);
builder.delete(0, builder.length());
}
// 从大写字母中排除字符
if(containUpperCase) {
arr = uppercaseLetter.toCharArray();
for (char sch : arr) {
if (excludeLetters.indexOf(sch) != -1)
continue;
builder.append(sch);
}
uppercaseLetter = builder.toString();
allStringBuilder.append(uppercaseLetter);
builder.delete(0, builder.length());
}
// 从小写子母中排除字符
if(containLowerCase) {
arr = lowerCaseLetters.toCharArray();
for (char sch : arr) {
if (excludeLetters.indexOf(sch) != -1)
continue;
builder.append(sch);
}
lowerCaseLetters = builder.toString();
allStringBuilder.append(lowerCaseLetters);
builder.delete(0, builder.length());
}
// 从特殊字符中排除字符
if(containSpecSymbol) {
arr = specialSymbol.toCharArray();
for (char sch : arr) {
if (excludeLetters.indexOf(sch) != -1)
continue;
builder.append(sch);
}
specialSymbol = builder.toString();
allStringBuilder.append(specialSymbol);
builder.delete(0, builder.length());
}
// 将排除过的字符(大写,小写,数字,特殊字符)组成一个新的字符集,这里我们称作字符总集
String allLetters = allStringBuilder.toString();
System.out.println( "nums :" + nums + "\r\n" +
"uppercaseLetter :" + uppercaseLetter + "\r\n" +
"lowerCaseLetters :" + lowerCaseLetters + "\r\n" +
"specialSymbol :" + specialSymbol + "\r\n" +
"allLetters :" + allLetters + "\r\n");
// 逻辑: 包含谁先从数组里面取一个,保证它有这个字符。例如包含特殊符号,那先取一个特殊符号到密码区
// 取完包含的后 再随机取其他的字符,最后将取的字符随机排列组合
// 我们取随机字符是从已经排除了不需要的字符的字符集中取的
Random random = new Random();
char[] passwordLetters = new char[passwordLength];
int rmn;
StringBuilder passwordBuilder = new StringBuilder();
// 生成N个密码
for(int k = 0; k < howMany; k++) {
int index = 0;
// 如果生成的密码里面必须包含数字,那我们先随机取一个数字,后面我们会添加都密码里面
// 以保证密码里面必须含有一个数字
if (containNums) {
rmn = random.nextInt(nums.length());
passwordLetters[index] = nums.charAt(rmn);
index++;
}
// 如果生成的密码里面必须包含大写字母,那我们先随机取一个大写字母
if (containUpperCase) {
rmn = random.nextInt(uppercaseLetter.length());
passwordLetters[index] = uppercaseLetter.charAt(rmn);
index++;
}
// 如果生成的密码里面必须包含小写字母,那我们先随机取一个小写字母
if (containLowerCase) {
rmn = random.nextInt(lowerCaseLetters.length());
passwordLetters[index] = lowerCaseLetters.charAt(rmn);
index++;
}
// 如果生成的密码里面必须包含特殊字符,那我们先随机取一个特殊字符
if (containSpecSymbol) {
rmn = random.nextInt(specialSymbol.length());
passwordLetters[index] = specialSymbol.charAt(rmn);
index++;
}
// 上面我们已经取过了必须包含的字符,我们将剩下的字符从字符总集中随机取剩下的字符
for (int i = index; i < passwordLength; i++) {
rmn = random.nextInt(allLetters.length());
passwordLetters[i] = allLetters.charAt(rmn);
}
// 字符我们已经取完了,取的字符数量就是密码的长度,例如 密码长度是8,那么我们取的字符的数量也是8
// 但是我们取的字符太规律了(先必须包含的字符,后随即字符),不符合密码的规则,我们需要将他们的顺序打乱
// 我们通过位置生成随机数,将随机数位置的字符和当前位置的字符交换位置达到随机效果
for (int i = 0; i < passwordLength; i++) {
rmn = random.nextInt(passwordLength);
char curr = passwordLetters[i];
char exchange = passwordLetters[rmn];
passwordLetters[i] = exchange;
passwordLetters[rmn] = curr;
}
passwordBuilder.append(passwordLetters).append("\r\n");
}
// 下来我们将程序运行的时间统计并输出
System.out.println("耗时:"+(System.currentTimeMillis() - startTime));
//System.out.println(passwordBuilder);
// 并将运算的结果放在剪贴板中,方便我们复制到文档中
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable tText = new StringSelection(passwordBuilder.toString());
clip.setContents(tText, null);
}
方法调用
public static void main(String[] args) {
//排除字符0OoB81lI ,包含大写字母,包含小写字母,包含数字,包含特殊字符,长度8,生成10000个,特殊字符集
generatePassword("0OoB81lI",true,true,true,true,8,10000,"~!@^*%");
}
附带密码检测器
检测生成的密码是否合格
private static void checkPasswordIsCorrect(){
File file = new File("C:\\Users\\1002212\\Desktop\\445566.txt");
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String tempString ;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
// 显示行号
if(!tempString.matches("^[0-9A-Za-z~!@^*#$%]{8}$")){
System.out.println("line " + line + ": " + tempString);
}
if(!tempString.matches(".*[0-9]+.*")
|| !tempString.matches(".*[A-Z]+.*")
|| !tempString.matches(".*[a-z]+.*")
|| !tempString.matches(".*[~!@^*#$%]+.*")){
System.out.println("line " + line + ": " + tempString);
}
line++;
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}