반응형
해당 글에서는 Math 함수가 아닌 SecureRandom 함수를 이용하여 랜덤 한 숫자/문자(난수) 생성방법에 대해 알아봅니다.
1) Math.random() 함수를 사용하지 않는 이유
💡 Random 함수를 사용하지 않는 이유
- SonarQube를 통해서 Security Hotspots로 Math.random() 함수에서 아래와 같은 문제점이 발생하였습니다.
- 여기에서 이 의사 난수 생성기를 사용하는 것이 안전한지 확인하세요.(Make sure that using this pseudorandom number generator is safe here.)
- 해당 문제는 ‘난수 생성‘에 대해 보안에 민감하다는 문제점이 발생합니다. 이는 Math.random() 역시 난수를 생성하는 데 있어서 보안적으로 취약점이 있다는 문제점이 발생하였습니다.
💡 [참고] 또한 Math.random() 함수를 사용하면 안되는 이유
💡 [참고] Math.random()관련 취약점 관련 글
💡 [참고] SecureRandom API Document
2) 랜덤 숫자 생성
1. 자릿수 만큼 랜덤 숫자 생성
public class 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);
}
}
int randomNum = CommonUtils.generateRandomNum(6); // 894625
2. 시작 범위와 종료 범위의 랜덤 숫자(난수) 생성
public class CommonUtils {
/**
* 시작 범위(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);
}
}
int rangeRandomNum = CommonUtils.generateRangeRandomNum(1, 1000); // 644
3) 랜덤 문자 생성
1. 자릿수 만큼 랜덤 대문자/소문자 생성
public class CommonUtils {
/**
* 자릿수(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();
}
}
String randomStr = CommonUtils.generateRandomStr(5, true); // EJQOM
4) 랜덤 숫자 + 문자 조합 생성
1. 자릿수 만큼 랜덤 숫자 + 대문자/소문자 생성
public class CommonUtils {
/**
* 자릿수(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();
}
}
String randomMixStr = CommonUtils.generateRandomMixStr(10, true); // II9H2J0VIF
5) 종합
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 개발' 카테고리의 다른 글
[Java/Short] 하나의 배열 내 요소 비교 방법 : 전체 요소, 독립적 비교 (0) | 2024.02.12 |
---|---|
[Java/Short] IPv4, IPv6 정규 표현식(RegExp) 구성 방법 (4) | 2024.01.29 |
[Java/Short] 직렬화/역 직렬화 방법 : jackson-binding (0) | 2024.01.04 |
[Java/Short] 문자열의 문자를 가장 앞으로/뒤로 이동하는 방법 (0) | 2023.11.04 |
[Java/Short] 배열을 반으로 나누어 재구성 방법 : for, Arrays.copyOfRange (0) | 2023.11.03 |