Java/Short 개발

[Java/Short] SecureRandom을 이용한 랜덤 문자열 생성 방법: 숫자, 문자, 특수문자 조합, 임시 비밀번호

adjh54 2024. 2. 15. 11:36
반응형
해당 글에서는 SecureRandom 클래스를 사용하여서 랜덤 문자열을 생성하는 방법에 대해 알아봅니다. 또한 임시 비밀번호로 이용할 수 있는 방법에 대해서도 알아봅니다.






 

1) SecureRandom을 이용한 랜덤 숫자/문자(난수) 생성방법


💡 SecureRandom을 이용한 랜덤 숫자/문자(난수) 생성방법

- 아래의 글을 참고하시면 이전에 작성한 글을 확인하실 수 있습니다.
import java.security.SecureRandom;

/**
 * 공통 유틸
 *
 * @author : lee
 * @fileName : CommonUtils
 * @since : 1/22/24
 */
public class CommonUtils {

    private CommonUtils() {
    }

    /**
     * 자릿수(digit) 만큼 랜덤한 숫자를 반환 받습니다.
     *
     * @param length 자릿수
     * @return 랜덤한 숫자
     */
    public static int generateRandomNum(int length) {
        SecureRandom secureRandom = new SecureRandom();
        int upperLimit = (int) Math.pow(10, length);
        return secureRandom.nextInt(upperLimit);
    }

    /**
     * 시작 범위(start)와 종료 범위(end) 값을 받아서 랜덤한 숫자를 반환 받습니다.
     *
     * @param start 시작 범위
     * @param end   종료 범위
     * @return 랜덤한 숫자
     */
    public static int generateRangeRandomNum(int start, int end) {
        SecureRandom secureRandom = new SecureRandom();
        return start + secureRandom.nextInt(end + 1);
    }

    /**
     * 자릿수(length) 만큼 랜덤한 문자열을 대문자/소문자에 따라 반환 받습니다.
     *
     * @param length      자릿수
     * @param isUpperCase 대문자 여부
     * @return 랜덤한 문자열
     */
    public static String generateRandomStr(int length, boolean isUpperCase) {
        String alphabet = "abcdefghijklmnopqrstuvwxyz";
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(alphabet.charAt(secureRandom.nextInt(alphabet.length())));
        }
        return isUpperCase ? sb.toString().toUpperCase() : sb.toString().toLowerCase();
    }

    /**
     * 자릿수(length) 만큼 랜덤한 숫자 + 문자 조합을 대문자/소문자에 따라 반환 받습니다.
     *
     * @param length      자릿수
     * @param isUpperCase 대문자 여부
     * @return 랜덤한 숫자 + 문자 조합의 문자열
     */
    public static String generateRandomMixStr(int length, boolean isUpperCase) {
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);

        for (int i = 0; i < length; i++) {
            int index = random.nextInt(characters.length());
            sb.append(characters.charAt(index));
        }
        return isUpperCase ? sb.toString() : sb.toString().toLowerCase();
    }

}

 

💡 [참고] 간단한 숫자, 문자 간의 난수를 만드는 방법입니다.

[Java/Short] SecureRandom을 이용한 랜덤 숫자/문자(난수) 생성 방법

해당 글에서는 Math 함수가 아닌 SecureRandom 함수를 이용하여 랜덤 한 숫자/문자(난수) 생성방법에 대해 알아봅니다. 1) Math.random() 함수를 사용하지 않는 이유 💡 Random 함수를 사용하지 않는 이유 -

adjh54.tistory.com

 
 
 
 

2) 랜덤 문자열 만들기: 문자 + 특수문자 조합


💡 랜덤 문자열 만들기: 문자 + 특수문자 조합

- 해당 만드는 방법의 조합은 ASCII 코드를 기반으로 특정 범위의 조합을 기반으로 랜덤 하게 문자를 추출하여 조합하도록 구성하였습니다.
분류포함여부ASCII Code Range
특수문자포함33 ~ 47, 58 ~ 64, 91 ~ 96
대문자포함65 ~ 90
소문자포함97 ~ 122
숫자미 포함47 ~ 57

 
 

/**
 * 자릿수(length) 만큼 랜덤한 문자와 특수문자 조합의 랜덤한 문자열을 출력합니다.
 *
 * @param length 문자의 범위
 * @return String 문자 + 특수 문자 조합 문자열
 */
public static String generateRandomMixCharNSpecialChar(int length) {
    SecureRandom secureRandom = new SecureRandom();

    /*
     * 1. 특수문자의 범위: 33 ~ 47, 58 ~ 64, 91 ~ 96
     * 2. 대문자의 범위: 65 ~ 90
     * 3. 소문자의 범위: 97 ~ 122
     * -- 제외 대상 범위(숫자) : 48 ~ 57
     */
    String charNSpecialChar = IntStream.concat(
                    IntStream.rangeClosed(33, 47),
                    IntStream.rangeClosed(58, 126))
            .mapToObj(i -> String.valueOf((char) i))
            .collect(Collectors.joining());

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < length; i++) {
        builder.append(charNSpecialChar.charAt(secureRandom.nextInt(charNSpecialChar.length())));
    }
    return builder.toString();
}

// 호출부
String randomValue = CommonUtils.generateRandomMixCharNSpecialChar(8);    // [공통함수] 문자 + 특수문자 조합 문자열 생성

// 출력 값 예시
System.out.println("random value :: "+ randomValue); // random value :: .^lmI\\i_

 
 
 

3) 랜덤 문자열 만들기: 숫자 + 특수문자 조합


💡 랜덤 문자열 만들기: 숫자 + 특수문자 조합

- 해당 만드는 방법의 조합은 ASCII 코드를 기반으로 특정 범위의 조합을 기반으로 랜덤하게 문자를 추출하여 조합하도록 구성하였습니다.

 

분류포함 여부ASCII Code Range
특수문자포함33 ~ 47, 58 ~ 64, 91 ~ 96
숫자포함47 ~ 57
대문자미 포함65 ~ 90
소문자미 포함97 ~ 122

 
 

/**
 * 자릿수(length) 만큼 랜덤한 숫자와 특수문자 조합의 랜덤한 문자열을 출력합니다.
 *
 * @param length 문자의 범위
 * @return String 숫자 + 특수 문자 조합 문자열
 */
public static String generateRandomMixNumNSpecialChar(int length) {
    SecureRandom secureRandom = new SecureRandom();

    /*
     * 1. 특수문자의 범위 33 ~ 47, 58 ~ 64, 91 ~ 96
     * 2. 숫자의 범위 : 48 ~ 57
     * -- 대문자의 범위(제외): 65 ~ 90
     * -- 소문자의 범위(제외): 97 ~ 122
     */
    String charNSpecialChar = IntStream.concat(
                    IntStream.rangeClosed(33, 64),
                    IntStream.concat(
                            IntStream.rangeClosed(91, 96),
                            IntStream.rangeClosed(123, 126)))
            .mapToObj(i -> String.valueOf((char) i))
            .collect(Collectors.joining());

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < length; i++) {
        builder.append(charNSpecialChar.charAt(secureRandom.nextInt(charNSpecialChar.length())));
    }
    return builder.toString();
}

// 호출부 
String randomValue = CommonUtils.generateRandomMixNumNSpecialChar(8);    // [공통함수] 숫자 + 특수문자 조합 문자열 생성

// 출력 값 예시 
System.out.println("random value :: "+ randomValue); // random value :: <61[>*?.

 
 
 
 

4) 랜덤 문자열 만들기 : 문자 + 숫자 + 특수문자 조합


💡 랜덤 문자열 만들기 : 문자 + 숫자 + 특수문자 조합

- 해당 만드는 방법의 조합은 ASCII 코드를 기반으로 특정 범위의 조합을 기반으로 랜덤하게 문자를 추출하여 조합하도록 구성하였습니다.
분류포함여부ASCII Code Range
특수문자포함33 ~ 47, 58 ~ 64, 91 ~ 96
숫자포함47 ~ 57
대문자포함65 ~ 90
소문자포함97 ~ 122

 

/**
 * 자릿수(length) 만큼 랜덤한 숫자 + 문자 + 특수문자 조합의 랜덤한 문자열을 출력합니다.
 *
 * @param length 문자의 범위
 * @return String 숫자 + 문자 + 특수 문자 조합 문자열
 */
public static String generateRandomMixAll(int length) {
    SecureRandom secureRandom = new SecureRandom();
    /*
     * 1. 특수문자의 범위 33 ~ 47, 58 ~ 64, 91 ~ 96
     * 2. 숫자의 범위 : 48 ~ 57
     * 3. 대문자의 범위: 65 ~ 90
     * 4. 소문자의 범위: 97 ~ 122
     */
    String charNSpecialChar =
            IntStream.rangeClosed(33, 126)
                    .mapToObj(i -> String.valueOf((char) i))
                    .collect(Collectors.joining());

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < length; i++) {
        builder.append(charNSpecialChar.charAt(secureRandom.nextInt(charNSpecialChar.length())));
    }
    return builder.toString();
}

// 호출부
String randomValue = CommonUtils.generateRandomMixCharNSpecialChar(8);    // [공통함수] 숫자 + 문자 + 특수문자 조합 문자열 생성

// 출력 값 예시
System.out.println("random value :: "+ randomValue); // random value :: 2^e0M?S5

 
 

5) 임시비밀번호 활용방법


 

1. 숫자 + 소문자 조합의 임시 비밀번호


💡 숫자 + 소문자 조합의 임시 비밀번호

- 임시비밀번호로 자주 사용되는 숫자 + 소문자 조합의 임시 비밀번호로 구성된 랜덤한 숫자가 출력되도록 구성하였습니다.

- 해당 만드는 방법의 조합은 ASCII 코드를 기반으로 특정 범위의 조합을 기반으로 랜덤하게 문자를 추출하여 조합하도록 구성하였습니다.
/**
 * 자릿수(length) 만큼 랜덤한 숫자 소문자 조합의 랜덤한 문자열을 출력합니다.
 *
 * @param length 문자의 범위
 * @return String 숫자 + 소문자 조합의 랜덤한 문자열을 출력합니다.
 */
public static String generateRandomTempPasswordType1(int length) {
    SecureRandom secureRandom = new SecureRandom();
    /*
     * 1. 소문자의 범위: 97 ~ 122
     * 2. 숫자의 범위 : 48 ~ 57
     * -- 대문자의 범위(제외): 65 ~ 90
     * -- 특수문자의 범위(제외): 33 ~ 47, 58 ~ 64, 91 ~ 96
     */
    String tempPassword =
            IntStream.rangeClosed(33, 126)
                    .mapToObj(i -> String.valueOf((char) i))
                    .collect(Collectors.joining());

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < length; i++) {
        builder.append(tempPassword.charAt(secureRandom.nextInt(tempPassword.length())));
    }
    return builder.toString();
}

// 호출부
String randomValue = CommonUtils.generateRandomTempPasswordType1(8);    // [공통함수] 숫자 + 소문자 조합 문자열 생성

// 출력 값 예시
System.out.println("random value :: "+ randomValue); // random value :: swc1um71

 
 
 
 

2. 문자 + 일부 특수문자 조합의 임시 비밀번호


💡 문자 + 일부 특수문자 조합의 임시 비밀번호

- 문자(대문자, 소문자) 조합에 일부 허용되는 특수문자에 조합('!', '@', '#', '$', '%', '^', '&', '_', '=', '+’)으로 임시비밀번호를 생성합니다.
/**
 * 자릿수(length) 만큼 랜덤한 숫자 소문자 조합의 랜덤한 문자열을 출력합니다.
 *
 * @param length 문자의 범위
 * @return String 숫자 + 소문자 조합의 랜덤한 문자열을 출력합니다.
 */
public static String generateRandomTempPasswordType2(int length) {
    SecureRandom secureRandom = new SecureRandom();
    /*
     * 1. 소문자의 범위 : 97 ~ 122
     * 2. 대문자의 범위 : 65 ~ 90
     * 3. 일부 허용 특수문자 : !@#$%^&_=+
     */
    String tempPasswordStr = IntStream.concat(
                    IntStream.concat(
                            IntStream.rangeClosed(65, 90),
                            IntStream.rangeClosed(97, 122)),
                    "!@#$%^&_=+".chars())
            .mapToObj(i -> String.valueOf((char) i))
            .collect(Collectors.joining());
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < length; i++) {
        builder.append(tempPasswordStr.charAt(secureRandom.nextInt(tempPasswordStr.length())));
    }
    return builder.toString();
}

// 호출부
String randomValue = CommonUtils.generateRandomTempPasswordType2(8);    // [공통함수] 문자 + 일부 특수문자 조합 문자열 생성

// 출력 값 예시
System.out.println("random value :: "+ randomValue); // random value :: BRN$sX_P

 
 
 

6) 종합


/**
 * 공통 유틸
 *
 * @author : lee
 * @fileName : CommonUtils
 * @since : 1/22/24
 */
public class CommonUtils {

    private CommonUtils() {
    }

    /**
     * 자릿수(digit) 만큼 랜덤한 숫자를 반환 받습니다.
     *
     * @param length 자릿수
     * @return 랜덤한 숫자
     */
    public static int generateRandomNum(int length) {
        SecureRandom secureRandom = new SecureRandom();
        int upperLimit = (int) Math.pow(10, length);
        return secureRandom.nextInt(upperLimit);
    }

    /**
     * 시작 범위(start)와 종료 범위(end) 값을 받아서 랜덤한 숫자를 반환 받습니다.
     *
     * @param start 시작 범위
     * @param end   종료 범위
     * @return 랜덤한 숫자
     */
    public static int generateRangeRandomNum(int start, int end) {
        SecureRandom secureRandom = new SecureRandom();
        return start + secureRandom.nextInt(end + 1);
    }

    /**
     * 자릿수(length) 만큼 랜덤한 문자열을 대문자/소문자에 따라 반환 받습니다.
     *
     * @param length      자릿수
     * @param isUpperCase 대문자 여부
     * @return 랜덤한 문자열
     */
    public static String generateRandomStr(int length, boolean isUpperCase) {
        String alphabet = "abcdefghijklmnopqrstuvwxyz";
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(alphabet.charAt(secureRandom.nextInt(alphabet.length())));
        }
        return isUpperCase ? sb.toString().toUpperCase() : sb.toString().toLowerCase();
    }

    /**
     * 자릿수(length) 만큼 랜덤한 숫자 + 문자 조합을 대문자/소문자에 따라 반환 받습니다.
     *
     * @param length      자릿수
     * @param isUpperCase 대문자 여부
     * @return 랜덤한 숫자 + 문자 조합의 문자열
     */
    public static String generateRandomMixStr(int length, boolean isUpperCase) {
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);

        for (int i = 0; i < length; i++) {
            int index = random.nextInt(characters.length());
            sb.append(characters.charAt(index));
        }
        return isUpperCase ? sb.toString() : sb.toString().toLowerCase();
    }

    /**
     * 자릿수(length) 만큼 랜덤한 문자와 특수문자 조합의 랜덤한 문자열을 출력합니다.
     *
     * @param length 문자의 범위
     * @return String 문자 + 특수 문자 조합 문자열
     */
    public static String generateRandomMixCharNSpecialChar(int length) {
        SecureRandom secureRandom = new SecureRandom();

        /*
         * 1. 특수문자의 범위: 33 ~ 47, 58 ~ 64, 91 ~ 96
         * 2. 대문자의 범위: 65 ~ 90
         * 3. 소문자의 범위: 97 ~ 122
         * -- 제외 대상 범위(숫자) : 48 ~ 57
         */
        String charNSpecialChar = IntStream.concat(
                        IntStream.rangeClosed(33, 47),
                        IntStream.rangeClosed(58, 126))
                .mapToObj(i -> String.valueOf((char) i))
                .collect(Collectors.joining());

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            builder.append(charNSpecialChar.charAt(secureRandom.nextInt(charNSpecialChar.length())));
        }
        return builder.toString();
    }

    /**
     * 자릿수(length) 만큼 랜덤한 숫자와 특수문자 조합의 랜덤한 문자열을 출력합니다.
     *
     * @param length 문자의 범위
     * @return String 숫자 + 특수 문자 조합 문자열
     */
    public static String generateRandomMixNumNSpecialChar(int length) {
        SecureRandom secureRandom = new SecureRandom();

        /*
         * 1. 특수문자의 범위 33 ~ 47, 58 ~ 64, 91 ~ 96
         * 2. 숫자의 범위 : 48 ~ 57
         * -- 대문자의 범위(제외): 65 ~ 90
         * -- 소문자의 범위(제외): 97 ~ 122
         */
        String charNSpecialChar = IntStream.concat(
                        IntStream.rangeClosed(33, 64),
                        IntStream.concat(
                                IntStream.rangeClosed(91, 96),
                                IntStream.rangeClosed(123, 126)))
                .mapToObj(i -> String.valueOf((char) i))
                .collect(Collectors.joining());

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            builder.append(charNSpecialChar.charAt(secureRandom.nextInt(charNSpecialChar.length())));
        }
        return builder.toString();
    }


    /**
     * 자릿수(length) 만큼 랜덤한 숫자 + 문자 + 특수문자 조합의 랜덤한 문자열을 출력합니다.
     *
     * @param length 문자의 범위
     * @return String 숫자 + 문자 + 특수 문자 조합 문자열
     */
    public static String generateRandomMixAll(int length) {
        SecureRandom secureRandom = new SecureRandom();
        /*
         * 1. 특수문자의 범위 33 ~ 47, 58 ~ 64, 91 ~ 96
         * 2. 숫자의 범위 : 48 ~ 57
         * 3. 대문자의 범위: 65 ~ 90
         * 4. 소문자의 범위: 97 ~ 122
         */
        String charNSpecialChar =
                IntStream.rangeClosed(33, 126)
                        .mapToObj(i -> String.valueOf((char) i))
                        .collect(Collectors.joining());

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            builder.append(charNSpecialChar.charAt(secureRandom.nextInt(charNSpecialChar.length())));
        }
        return builder.toString();
    }


    /**
     * 자릿수(length) 만큼 랜덤한 숫자 소문자 조합의 랜덤한 문자열을 출력합니다.
     *
     * @param length 문자의 범위
     * @return String 숫자 + 소문자 조합의 랜덤한 문자열을 출력합니다.
     */
    public static String generateRandomTempPasswordType1(int length) {
        SecureRandom secureRandom = new SecureRandom();
        /*
         * 1. 소문자의 범위: 97 ~ 122
         * 2. 숫자의 범위 : 48 ~ 57
         * -- 대문자의 범위(제외): 65 ~ 90
         * -- 특수문자의 범위(제외): 33 ~ 47, 58 ~ 64, 91 ~ 96
         */
        String tempPassword =
                IntStream.concat(
                        IntStream.rangeClosed(48, 57),
                        IntStream.rangeClosed(97, 122))
                        .mapToObj(i -> String.valueOf((char) i))
                .collect(Collectors.joining());

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            builder.append(tempPassword.charAt(secureRandom.nextInt(tempPassword.length())));
        }
        return builder.toString();
    }

    /**
     * 자릿수(length) 만큼 랜덤한 숫자 소문자 조합의 랜덤한 문자열을 출력합니다.
     *
     * @param length 문자의 범위
     * @return String 숫자 + 소문자 조합의 랜덤한 문자열을 출력합니다.
     */
    public static String generateRandomTempPasswordType2(int length) {
        SecureRandom secureRandom = new SecureRandom();
        /*
         * 1. 소문자의 범위 : 97 ~ 122
         * 2. 대문자의 범위 : 65 ~ 90
         * 3. 일부 허용 특수문자 : !@#$%^&_=+
         */
        String tempPasswordStr = IntStream.concat(
                        IntStream.concat(
                                IntStream.rangeClosed(65, 90),
                                IntStream.rangeClosed(97, 122)),
                        "!@#$%^&_=+".chars())
                .mapToObj(i -> String.valueOf((char) i))
                .collect(Collectors.joining());
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            builder.append(tempPasswordStr.charAt(secureRandom.nextInt(tempPasswordStr.length())));
        }
        return builder.toString();
    }
}

 
 
 
 
오늘도 감사합니다. 😀
 
 
 

반응형