十个方法破解Java生成随机密码的小窍门

文摘   2024-11-07 19:42   广东  

最近有个需求需要生成随机密码,方法很多。总结几种常用的方法。

  • 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中的SecureRandomBase64

更安全的随机密码,可以使用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语句的七种绝佳方法实战

SpringBoot使用EasyExcel并行导出多个excel文件并压缩zip下载
提升编程效率的利器: Google Guava库中双向映射BitMap
从MySQL行格式原理看:为什么开发规范中不推荐NULL?数据是如何在磁盘上存储的?
SpringBoot中使用Jackson实现自定义序列化和反序列化控制的5种方式总结

提升编程效率的利器: Google Guava库之RateLimiter优雅限流

深入JVM逃逸分析原理:且看其如何提高程序性能和内存利用率

必知必会!MySQL索引下推:原理与实战

深入解析JVM内存分配优化技术:TLAB

SpringBoot中基于JWT的双token(access_token+refresh_token)授权和续期方案
SpringBoot中基于JWT的单token授权和续期方案
SpringBoot中Token登录授权、续期和主动终止的方案(Redis+Token)
微服务中token鉴权设计的4种方式总结
提升编程效率的API利器:精通Google Guava库区间范围映射RangeMap
SpringBoot中Jackson控制序列化和反序列化的注解和扩展点总结【收藏版】

SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载

提升编程效率的API利器:精通Google Guava库之IO工具类
提升编程效率的API利器:精通Google Guava库二维映射表Table
提升编程效率的API利器:精通Google Guava库区间范围映射RangeMap
提升编程效率的利器: Google Guava库中双向映射BitMap
提升编程效率的利器: Google Guava库之RateLimiter优雅限流
基于Guava布隆过滤器的海量字符串高效去重实践
加密算法理论总结:分类与典型算法
每个后端开发人员都应该问的发人深省的问题
提升编程效率的API利器:40个示例精通Google Guava库常用工具
MySQL高级优化技巧:使用Hints精准控制查询优化器的选择
每个后端开发人员都应该问的发人深省的问题

Elasticsearch揭秘:高效写入与精准检索的流程原理全解析


关注『 码到三十五 』,日有所获
                     点赞 和 在看 就是最大的支持

码到三十五
主要分享正经的开发技术(原理,架构,实践,源码等),以输出驱动输入;当然偶尔会穿插点生活琐碎,顺便吃个瓜,目的嘛,搞点精准流量,看能不能发发广告。
 最新文章