❝最近有个需求需要生成随机密码,方法很多。总结几种常用的方法。
❞
1. 使用Java标准库中的`Random`类
2. 使用Java 8中的`SecureRandom`和`Base64`类
3. 使用`ThreadLocalRandom`
4. 使用`java.util.Collections.shuffle()`
5. 使用第三方库
6. 结合多种字符类型
7. 使用Google的Guava库
8. 使用`Base64`编码生成密码
9. 自定义字符集和密码长度
10. 结合固定和随机字符
11. 使用正则表达式
1. 使用Java标准库中的Random
类
import java.util.Random;
public class RandomPasswordGenerator {
private static final String CHAR_LIST = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
private static final int LENGTH = 10;
public static void main(String[] args) {
System.out.println(generateRandomPassword());
}
public static String generateRandomPassword() {
Random random = new Random();
StringBuilder password = new StringBuilder();
for (int i = 0; i < LENGTH; i++) {
int index = random.nextInt(CHAR_LIST.length());
password.append(CHAR_LIST.charAt(index));
}
return password.toString();
}
}
2. 使用Java 8中的SecureRandom
和Base64
类
更安全的随机密码,可以使用SecureRandom
类,它提供了更好的随机性。同时可以使用Base64编码来确保密码包含特殊字符。
import java.security.SecureRandom;
import java.util.Base64;
public class SecureRandomPasswordGenerator {
private static final int LENGTH = 20; // Base64编码后的长度
public static void main(String[] args) {
System.out.println(generateSecureRandomPassword());
}
public static String generateSecureRandomPassword() {
SecureRandom random = new SecureRandom();
byte[] passwordBytes = new byte[LENGTH];
random.nextBytes(passwordBytes);
// Base64编码,然后去掉末尾的'='字符,因为它可能会引起一些问题
String password = Base64.getEncoder().encodeToString(passwordBytes).replaceAll("=", "");
// Base64编码后的字符串可能会比原始字节数组长,所以我们需要截取所需长度的部分
return password.substring(0, Math.min(password.length(), LENGTH));
}
}
由于Base64编码的特性,生成的密码可能包含/
、+
和=
等特殊字符。
3. 使用ThreadLocalRandom
ThreadLocalRandom
类是Java 7引入的,提供了更好的线程安全性以及在某些情况下的更高性能。
import java.util.concurrent.ThreadLocalRandom;
public class PasswordGenerator {
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|:;\"'<,>.?/";
private static final int PASSWORD_LENGTH = 12;
public static String generatePassword() {
char[] password = new char[PASSWORD_LENGTH];
for (int i = 0; i < PASSWORD_LENGTH; i++) {
int index = ThreadLocalRandom.current().nextInt(CHARACTERS.length());
password[i] = CHARACTERS.charAt(index);
}
return new String(password);
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
4. 使用java.util.Collections.shuffle()
可以创建一个字符列表,然后使用Collections.shuffle()
方法来随机打乱它,最后从打乱的列表中选取字符来构建密码。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PasswordGenerator {
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|:;\"'<,>.?/";
private static final int PASSWORD_LENGTH = 12;
public static String generatePassword() {
List<Character> charactersList = new ArrayList<>();
for (char c : CHARACTERS.toCharArray()) {
charactersList.add(c);
}
Collections.shuffle(charactersList);
StringBuilder password = new StringBuilder();
for (int i = 0; i < PASSWORD_LENGTH; i++) {
password.append(charactersList.get(i));
}
return password.toString();
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
5. 使用第三方库
还可以使用像Apache Commons Lang或Google Guava这样的第三方库来生成随机密码。这些库通常提供了现成的工具类和方法来简化随机字符串的生成。
如在Apache Commons Lang中,可以使用RandomStringUtils
类:
import org.apache.commons.lang3.RandomStringUtils;
public class PasswordGenerator {
private static final int PASSWORD_LENGTH = 12;
public static String generatePassword() {
return RandomStringUtils.randomAlphanumeric(PASSWORD_LENGTH) +
RandomStringUtils.randomAscii(2).replaceAll("\\W", ""); // To include special characters
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
6. 结合多种字符类型
如需要确保密码包含大写字母、小写字母、数字和特殊字符,可以分别从这些类型的字符集中随机选择字符,然后组合它们来生成密码。
import java.util.Random;
public class ComplexPasswordGenerator {
private static final String UPPER_ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHA = "abcdefghijklmnopqrstuvwxyz";
private static final String NUMBERS = "0123456789";
private static final String SPECIAL_CHARS = "~`!@#$%^&*()_-+={[}]|:;\"'<,>.?/";
private static final int PASSWORD_LENGTH = 12;
public static String generatePassword() {
Random rand = new Random();
StringBuilder password = new StringBuilder();
// Ensure at least one character from each group
password.append(UPPER_ALPHA.charAt(rand.nextInt(UPPER_ALPHA.length())));
password.append(LOWER_ALPHA.charAt(rand.nextInt(LOWER_ALPHA.length())));
password.append(NUMBERS.charAt(rand.nextInt(NUMBERS.length())));
password.append(SPECIAL_CHARS.charAt(rand.nextInt(SPECIAL_CHARS.length())));
// Fill the rest with characters from all groups
for (int i = 4; i < PASSWORD_LENGTH; i++) {
String characterSet = getRandomCharacterSet(rand);
password.append(characterSet.charAt(rand.nextInt(characterSet.length())));
}
return password.toString();
}
private static String getRandomCharacterSet(Random rand) {
int randomIndex = rand.nextInt(4);
switch (randomIndex) {
case 0:
return UPPER_ALPHA;
case 1:
return LOWER_ALPHA;
case 2:
return NUMBERS;
default:
return SPECIAL_CHARS;
}
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
首先确保密码至少包含一个大写字母、一个小写字母、一个数字和一个特殊字符,然后随机从所有字符集中选择字符来填充密码的其余部分。
7. 使用Google的Guava库
Guava库提供了很多实用的工具,包括生成随机字符串的功能:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
使用Guava的CharMatcher和CharSource来生成密码:
import com.google.common.base.CharMatcher;
import com.google.common.math.IntMath;
import com.google.common.collect.ImmutableList;
import java.security.SecureRandom;
import java.util.List;
import java.util.Random;
public class GuavaPasswordGenerator {
private static final int PASSWORD_LENGTH = 12;
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|:;\"'<,>.?/";
private static final List<Character> CHARACTER_LIST = ImmutableList.copyOf(CHARACTERS.chars().mapToObj(c -> (char) c).collect(ImmutableList.toImmutableList()));
public static String generatePassword() {
Random random = new SecureRandom();
String password = CharMatcher.any().retainFrom(
CharSource.fromChars(CHARACTER_LIST)
.sampled(IntMath.checkedMultiply(PASSWORD_LENGTH, 4)) // 多取一些字符以增加随机性
.retainAll(CharMatcher.anyOf(CHARACTERS))
.toString(),
PASSWORD_LENGTH);
return password;
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
8. 使用Base64
编码生成密码
Base64编码可以将任意二进制数据转换为由64个特定字符组成的文本格式。我们可以生成随机的字节数组,然后将其编码为Base64字符串,最后截取所需的长度作为密码。
import java.util.Base64;
import java.security.SecureRandom;
import java.nio.charset.StandardCharsets;
public class Base64PasswordGenerator {
private static final int BYTE_ARRAY_LENGTH = 9; // Base64编码后会变得更长,所以需要更短的字节数组来达到期望的密码长度
private static final int PASSWORD_LENGTH = 12; // 最终的密码长度
public static String generatePassword() {
SecureRandom random = new SecureRandom();
byte[] randomBytes = new byte[BYTE_ARRAY_LENGTH];
random.nextBytes(randomBytes);
// 使用Base64编码,然后截取所需长度的字符串作为密码
String base64Encoded = Base64.getEncoder().encodeToString(randomBytes);
return base64Encoded.substring(0, PASSWORD_LENGTH);
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
9. 自定义字符集和密码长度
指定用于生成密码的字符集和密码的长度。
import java.security.SecureRandom;
public class CustomPasswordGenerator {
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|:;\"'<,>.?/";
private static SecureRandom random = new SecureRandom();
public static String generatePassword(int length) {
if (length < 1) {
throw new IllegalArgumentException("Password length must be positive.");
}
StringBuilder password = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int index = random.nextInt(CHARACTERS.length());
password.append(CHARACTERS.charAt(index));
}
return password.toString();
}
public static void main(String[] args) {
int passwordLength = 16; // 自定义密码长度
System.out.println(generatePassword(passwordLength));
}
}
10. 结合固定和随机字符
先创建一个固定的模板字符串,然后在模板中的指定位置插入随机字符。
import java.security.SecureRandom;
public class TemplateBasedPasswordGenerator {
private static final String TEMPLATE = "AbcD-####-!";
private static final String NUMBERS = "0123456789";
public static String generatePassword() {
SecureRandom secureRandom = new SecureRandom();
StringBuilder password = new StringBuilder(TEMPLATE);
for (int i = 0; i < password.length(); i++) {
char c = password.charAt(i);
if (c == '#') {
int index = secureRandom.nextInt(NUMBERS.length());
password.setCharAt(i, NUMBERS.charAt(index));
}
}
return password.toString();
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
模板是"AbcD-####-!"
,#
字符会被随机数字替换。
11. 使用正则表达式
如需要密码符合特定的格式,可以使用正则表达式来验证生成的密码。
import java.security.SecureRandom;
import java.util.regex.Pattern;
public class RegexPasswordGenerator {
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|:;\"'<,>.?/";
private static final int PASSWORD_LENGTH = 12;
private static final Pattern PASSWORD_PATTERN = Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_\\-+={[}\\]|:;\"'<,>.?/]).{12}$");
public static String generatePassword() {
SecureRandom secureRandom = new SecureRandom();
StringBuilder password = new StringBuilder();
boolean isValid = false;
while (!isValid) {
password.setLength(0);
for (int i = 0; i < PASSWORD_LENGTH; i++) {
int index = secureRandom.nextInt(CHARACTERS.length());
password.append(CHARACTERS.charAt(index));
}
isValid = PASSWORD_PATTERN.matcher(password.toString()).matches();
}
return password.toString();
}
public static void main(String[] args) {
System.out.println(generatePassword());
}
}
PASSWORD_PATTERN
定义了一个正则表达式,要求密码至少包含一个小写字母、一个大写字母、一个数字和一个特殊字符,并且长度为12。
太强 ! SpringBoot中出入参增强的5种方法 : 加解密、脱敏、格式转换、时间时区处理
太强 ! SpringBoot中优化if-else语句的七种绝佳方法实战
提升编程效率的利器: Google Guava库之RateLimiter优雅限流
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
Elasticsearch揭秘:高效写入与精准检索的流程原理全解析