前言:
密码要求:
大写字符、小写字符、数字、特殊符号,必须要包含,密码长度在 8-20 位。
设计结果:
输入密码长度,返回符合要求的随机密码。
1.需求拆分
需求可分为两点:
- 四种字符必须包含
- 长度 8-20 位
2.逻辑设计
- 声明一个 list
- 把 4 种字符每种随机选一个放进 list
- 根据密码长度要求再随机选择4种字符放进list
- list 重新排序
- list 遍历组合成字符串输出
3.代码设计
- 首先写 4 个函数用于生成 4 种字符
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 要求:密码需要有大写、小写、特殊字符、长度在 8-20 位
*/
public class RandomPwd {
private static final String lowStr = "abcdefghijklmnopqrstuvwxyz";
private static final String specialStr = "~!@#$%^&*()_+/-=[]{};:'<>?.";
private static final String numStr = "0123456789";
// 随机获取字符串字符
private static char getRandomChar(String str) {
SecureRandom random = new SecureRandom();
return str.charAt(random.nextInt(str.length()));
}
// 随机获取小写字符
private static char getLowChar() {
return getRandomChar(lowStr);
}
// 随机获取大写字符
private static char getUpperChar() {
return Character.toUpperCase(getLowChar());
}
// 随机获取数字字符
private static char getNumChar() {
return getRandomChar(numStr);
}
// 随机获取特殊字符
private static char getSpecialChar() {
return getRandomChar(specialStr);
}
}
tip:
建议使用 SecureRandom 而不是 Random,Random 靠传入的种子计算,SecureRandom 靠随机事件进行计算,具有更好的随机性。
- 其次写一个函数用于指定调用 4 个函数的哪一个
private static char getRandomChar(int funNum) {
switch (funNum) {
case 0:
return getLowChar();
case 1:
return getUpperChar();
case 2:
return getNumChar();
default:
return getSpecialChar();
}
}
- 最后写一个函数用于组合上面函数功能,用于随机生成密码
private static String getRandomPwd(int num) {
if (num > 20 || num < 8) {
System.out.println("长度不满足要求");
return "";
}
// 先把 4 种字符每种来一个放进 list
List<Character> list = new ArrayList<>(num);
list.add(getLowChar());
list.add(getUpperChar());
list.add(getNumChar());
list.add(getSpecialChar());
// 因为已经把 4 种字符放进list了,所以 i 取值从 4开始
// 产生随机数用于随机调用生成字符的函数
for (int i = 4; i < num; i++) {
SecureRandom random = new SecureRandom();
int funNum = random.nextInt(4);
list.add(getRandomChar(funNum));
}
Collections.shuffle(list);
StringBuilder stringBuilder = new StringBuilder(list.size());
for (Character c : list) {
stringBuilder.append(c);
}
return stringBuilder.toString();
}
4.全量代码和测试
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 要求:密码需要有大写、小写、特殊字符、长度在 8-20 位
*/
public class RandomPwd {
private static final String lowStr = "abcdefghijklmnopqrstuvwxyz";
private static final String specialStr = "~!@#$%^&*()_+/-=[]{};:'<>?.";
private static final String numStr = "0123456789";
// 随机获取字符串字符
private static char getRandomChar(String str) {
SecureRandom random = new SecureRandom();
return str.charAt(random.nextInt(str.length()));
}
// 随机获取小写字符
private static char getLowChar() {
return getRandomChar(lowStr);
}
// 随机获取大写字符
private static char getUpperChar() {
return Character.toUpperCase(getLowChar());
}
// 随机获取数字字符
private static char getNumChar() {
return getRandomChar(numStr);
}
// 随机获取特殊字符
private static char getSpecialChar() {
return getRandomChar(specialStr);
}
//指定调用字符函数
private static char getRandomChar(int funNum) {
switch (funNum) {
case 0:
return getLowChar();
case 1:
return getUpperChar();
case 2:
return getNumChar();
default:
return getSpecialChar();
}
}
// 指定长度,随机生成复杂密码
private static String getRandomPwd(int num) {
if (num > 20 || num < 8) {
System.out.println("长度不满足要求");
return "";
}
List<Character> list = new ArrayList<>(num);
list.add(getLowChar());
list.add(getUpperChar());
list.add(getNumChar());
list.add(getSpecialChar());
for (int i = 4; i < num; i++) {
SecureRandom random = new SecureRandom();
int funNum = random.nextInt(4);
list.add(getRandomChar(funNum));
}
Collections.shuffle(list);
StringBuilder stringBuilder = new StringBuilder(list.size());
for (Character c : list) {
stringBuilder.append(c);
}
return stringBuilder.toString();
}
// 测试函数入口
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int num = 10;
System.out.println(getRandomPwd(num));
}
}
}
测试输出:
.s@K+T935N
9&5pvXl4D0
uZ1q'>42:N
17.q_Y]z{Z
!620oGTfM&
6O}8ugCfT)
#d2KS4<FDW
d3S5*9;P@_
]IM@2cG9+l
_5@0ci$dRP
这个密码几乎没有规律性。