java:隨機生成符合要求的複雜密碼

前言:

密碼要求:
大寫字符、小寫字符、數字、特殊符號,必須要包含,密碼長度在 8-20 位。

設計結果:
輸入密碼長度,返回符合要求的隨機密碼。

1.需求拆分

需求可分爲兩點:

  1. 四種字符必須包含
  2. 長度 8-20 位
2.邏輯設計
  1. 聲明一個 list
  2. 把 4 種字符每種隨機選一個放進 list
  3. 根據密碼長度要求再隨機選擇4種字符放進list
  4. list 重新排序
  5. list 遍歷組合成字符串輸出
3.代碼設計
  1. 首先寫 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 靠隨機事件進行計算,具有更好的隨機性。

  1. 其次寫一個函數用於指定調用 4 個函數的哪一個
    private static char getRandomChar(int funNum) {
        switch (funNum) {
            case 0:
                return getLowChar();
            case 1:
                return getUpperChar();
            case 2:
                return getNumChar();
            default:
                return getSpecialChar();
        }
    }
  1. 最後寫一個函數用於組合上面函數功能,用於隨機生成密碼
    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

這個密碼幾乎沒有規律性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章