在開發驗證碼、臨時密碼、API Token 等功能時,常需根據安全等級生成不同複雜度的隨機字串。本文提供一個可配置、可擴展的工具類實現,支援四種難度模式:
public class RandomStringGenerator {
private static final SecureRandom RANDOM = new SecureRandom();
private static final String DIGITS = "0123456789";
private static final String LETTERS_LOWER = "abcdefghijklmnopqrstuvwxyz";
private static final String LEVEL2_CHARS = DIGITS + "abcd";
/**
* 生成指定長度與難度的隨機字串
* @param length 字串長度
* @param level 難度等級 1-4
* @return 隨機字串
*/
public static String generate(int length, int level) {
if (length <= 0) throw new IllegalArgumentException("長度必須 > 0");
if (level < 1 || level > 4) throw new IllegalArgumentException("難度需在 1-4 之間");
String pool = switch (level) {
case 1 -> DIGITS;
case 2 -> LEVEL2_CHARS;
case 3 -> LETTERS_LOWER;
case 4 -> DIGITS + LETTERS_LOWER;
default -> throw new IllegalStateException("未知難度");
};
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(pool.charAt(RANDOM.nextInt(pool.length())));
}
return sb.toString();
}
}
| 原版問題 | 優化方案 |
|---|---|
使用 Math.random() 非線程安全、低熵值 | 改用 SecureRandom,密碼學級安全 |
| 難度 4 每次循環重建字元池、索引邏輯錯誤 | 預先定義字元池,O(1) 取字元 |
| 硬編碼魔術數字、重複邏輯 | 常量化字元集,Switch Expression 簡潔分派 |
| 無參數校驗、難以擴展 | 加入守衛條款,支援自定義字元池擴展 |
// 生成包含大小寫、數字、特殊符號的高強度密碼
String strongPwd = RandomStringGenerator.generate(16,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*");
// 生成不含易混淆字元(0/O, 1/l, 8/B 等)的邀請碼
String inviteCode = RandomStringGenerator.generate(8,
"23456789ABCDEFGHJKLMNPQRSTUVWXYZ");
在 MacBook Pro M2 / JDK 21 環境下,生成 100 萬個長度 32 的字串:
若非安全敏感場景(如遊戲隨機名稱),可替換為 ThreadLocalRandom.current() 顯著提升吞吐。
通過字元池策略模式與 SecureRandom,我們獲得了一個安全、高效、易維護的隨機字串生成器。實際專案中建議封裝為工具類,並根據業務場景選擇合適的隨機源與字元集。