난수를 생성하는 방법 Java

⚡ 스마트 요약

난수 Java 이러한 랜덤 변수는 Random 클래스, Math.random, ThreadLocalRandom, SecureRandom 등 네 가지 관련 표준 라이브러리 옵션에서 제공되며, 각각 실제 응용 프로그램에 필요한 속도, 스레드 안전성 및 암호화 강도의 다양한 조합을 제공합니다.

  • 🎲 무작위 클래스: java.util.Random은 nextInt, nextLong, next를 노출합니다.Double일반적인 기본 데이터 유형의 경우 nextBoolean을 사용합니다.
  • 🧮 수학.랜덤: Math.random은 공유 Random 인스턴스를 사용하여 0.0(0.0 포함)에서 1.0(1.0 제외) 사이의 double 값을 반환합니다.
  • 🎯 사용자 지정 범위: nextInt에 범위를 지정하거나 Math.random의 스케일을 조정하여 임의의 최소값과 최대값 범위 내에서 값을 생성할 수 있습니다.
  • 🧵 나사산 안전: java.util.concurrent의 ThreadLocalRandom은 각 스레드에 자체 생성기를 제공하여 스레드 간 경쟁 상황에서 공유 Random보다 우수한 성능을 보입니다.
  • 🔐 보안 : java.security의 SecureRandom은 암호학적으로 강력한 암호값, 토큰 및 세션 키 값을 생성합니다.
  • 🌱 재현성 : 고정된 긴 값으로 난수 생성기를 시드하면 테스트 및 시뮬레이션이 실행 간에 결정론적으로 이루어집니다.

난수를 생성하는 방법 Java

무작위 숫자가 도처에 나타납니다 Java단위 테스트 데이터와 주사위 게임부터 세션 토큰과 섞인 카드 덱에 이르기까지, 이 튜토리얼에서는 난수를 생성하는 방법을 설명합니다. Java 표준 라이브러리의 모든 옵션을 사용하는 방법과 작업에 맞는 최적의 옵션을 선택하는 방법을 설명합니다.

난수 생성 Java

The Java 표준 라이브러리는 난수를 생성하는 네 가지 일반적인 방법을 제공합니다.

  • java.util.Random 이 클래스는 범용 클래스입니다. 이 클래스는 다음과 같은 메서드를 통해 boolean, int, long, float 및 double 값을 생성합니다. nextInt, nextLong예산 및 nextDouble.
  • Math.random 이 함수는 공유 변수를 사용하여 0.0(포함)에서 1.0(제외) 사이의 double 값을 반환하는 정적 헬퍼입니다. Random 내부적으로.
  • ThreadLocalRandom in java.util.concurrent 각 스레드에 자체 생성기를 제공하므로 여러 스레드가 단일 인스턴스를 두고 경쟁하지 않습니다.
  • SecureRandom in java.security 암호학적으로 강력한 의사 난수를 생성하여 암호, 세션 식별자 및 키에 사용합니다.

아래 섹션에서는 각 접근 방식을 사용하여 10개의 난수를 생성하는 방법을 보여줍니다.

예: 다음을 사용하여 난수 생성 Java 무작위 클래스

첫 번째 예시는 다음과 같습니다. java.util.Random 0부터 99까지의 정수 10개를 생성합니다.

import java.util.Random;

public class RandomNumbers {
    public static void main(String[] args) {
        Random objGenerator = new Random();
        for (int iCount = 0; iCount < 10; iCount++) {
            int randomNumber = objGenerator.nextInt(100);
            System.out.println("Random No : " + randomNumber);
        }
    }
}

출력:

Random No : 17
Random No : 57
Random No : 73
Random No : 48
Random No : 68
Random No : 86
Random No : 34
Random No : 97
Random No : 73
Random No : 18

인스턴스 Random 다음과 같이 생성됩니다. objGenerator. 그만큼 nextInt(int bound) 이 메서드는 0(포함)과 제공된 범위(제외) 사이의 값을 반환합니다. nextInt(100) 0부터 99까지의 값을 반환합니다. 이 시퀀스를 재현 가능하게 하려면 생성자에 시드 값을 전달하세요. 예를 들어, new Random(42)동일한 시드(seed)를 사용하면 항상 동일한 시퀀스가 ​​생성되므로 테스트 및 시뮬레이션에 유용합니다.

예: 사용 Java 수학.랜덤

0.0에서 1.0 사이의 난수 10개를 생성하려면 정적 함수를 호출하십시오. Math.random 메서드 내부 고리이것은 생성기 객체를 만들지 않고 무작위 double 값을 얻는 가장 빠른 방법입니다.

public class DemoRandom {
    public static void main(String[] args) {
        for (int xCount = 0; xCount < 10; xCount++) {
            System.out.println(Math.random());
        }
    }
}

출력:

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

후드, Math.random 단일 정적을 생성합니다 Random 최초 사용 시 및 통화 nextDouble 그 부분에 대해서는, 단일 공유 생성기는 데모에는 괜찮지만 멀티스레드 부하가 심해지면 병목 현상이 발생하는데, 다음 섹션에서 이 문제를 다룹니다.

사용자 지정 범위 내에서 난수 생성

실제 프로그램에서는 일반적으로 주사위 굴림의 경우 1에서 6 사이의 정수, 시뮬레이션의 경우 10.0에서 20.0 사이의 실수와 같이 특정 범위 내의 난수가 필요합니다. 두 가지 패턴으로 거의 모든 경우를 처리할 수 있습니다.

최소값과 최대값 사이의 임의의 정수 (최소값과 최대값 포함):

import java.util.Random;

public class RangeDemo {
    public static void main(String[] args) {
        Random rnd = new Random();
        int min = 1;
        int max = 6;
        // nextInt(max - min + 1) returns 0..(max-min), then shift by min
        int dice = rnd.nextInt(max - min + 1) + min;
        System.out.println("Dice roll : " + dice);
    }
}

최소값과 최대값 사이의 임의의 두 배 값:

double min = 10.0;
double max = 20.0;
double value = min + (max - min) * Math.random();
System.out.println("Value : " + value);

두 패턴 모두 생성기의 기본 범위에서 값을 가져와 대상 범위의 너비에 맞게 조정한 다음 최소값만큼 위로 이동시키는 방식으로 작동합니다. Java 버전 8 이상에서는 최신 버전을 통해 동일한 결과를 얻을 수 있습니다. ints, longs예산 및 doubles 스트림 메서드 Random예를 들어, rnd.ints(10, 1, 7).forEach(System.out::println) 주사위 10번 굴리는 동안.

멀티스레딩을 위한 ThreadLocalRandom Code

하나의 공유 Random 이 코드는 스레드 안전성이 확보되어 있지만, 모든 스레드가 동일한 내부 시드를 동기화해야 하므로 경합 상황에서는 속도가 느립니다. ThreadLocalRandom, 에 추가됨 Java 7살이고 살고 있어요 java.util.concurrent각 스레드에 자체 생성기를 제공하여 락 경합이 발생하지 않도록 합니다.

import java.util.concurrent.ThreadLocalRandom;

public class ThreadLocalDemo {
    public static void main(String[] args) {
        // random int in [1, 100]
        int i = ThreadLocalRandom.current().nextInt(1, 101);

        // random long in [1000, 5000]
        long l = ThreadLocalRandom.current().nextLong(1000L, 5001L);

        // random double in [0.0, 1.0)
        double d = ThreadLocalRandom.current().nextDouble();

        System.out.println(i + " " + l + " " + d);
    }
}

ThreadLocalRandom.current() 작업자 스레드, 병렬 스트림 및 모든 동시 작업 내부에서 발생합니다. 다음 사항에 유의하십시오. setSeed 발생 UnsupportedOperationException따라서 재현성을 위한 시드 설정은 지원되지 않습니다. 고정된 시드가 필요한 경우 일반 시드 방식을 사용하십시오. Random.

보안에 민감한 난수 생성을 위한 SecureRandom Numbers

의 인스턴스 Random ThreadLocalRandom 암호학적으로 안전하지 않습니다. 몇 개의 출력 샘플만 있으면 공격자는 내부 상태를 재구성하고 미래 값을 예측할 수 있습니다. 비밀번호, 세션 토큰, 솔트 값 및 암호화 키에는 보안 조치를 취하십시오. java.security.SecureRandom 대신에, 운영 체제 엔트로피 풀에서 초기 물질을 가져와 예측하기 어려운 값을 생성합니다.

import java.security.SecureRandom;

public class SecureDemo {
    public static void main(String[] args) {
        SecureRandom secure = new SecureRandom();

        byte[] token = new byte[16];
        secure.nextBytes(token);          // 128-bit random token

        int otp = secure.nextInt(1_000_000); // 6-digit one-time code

        System.out.println("OTP : " + String.format("%06d", otp));
    }
}

SecureRandom 보다 느립니다 Random 더 강력한 알고리즘과 풍부한 시드 자료를 사용하기 때문입니다. 보안 관련 작업에는 이 도구를 사용하고, 게임, 시뮬레이션 및 테스트 데이터에는 더 빠른 생성기를 사용하십시오.

자주 묻는 질문

java.util.Random 인스턴스를 생성하고 nextInt, nextLong, next를 호출합니다.Double또는 nextBoolean을 사용할 수도 있습니다. 간단하게 한 줄로 구현하려면 0.0에서 1.0 사이의 double 값을 반환하는 Math.random을 사용하세요. 두 가지 방법 모두 표준 라이브러리에 포함되어 있습니다.

정수의 경우 random.nextInt(max – min + 1) + min을 호출하고, 실수의 경우 min + (max – min) * Math.random()을 호출합니다. 이 공식은 생성기의 범위를 대상 창에 맞게 조정하고 최솟값만큼 이동합니다.

Random은 다양한 기본 데이터 유형에 대한 메서드를 제공하고 시드(seed) 기능을 지원하는 완전한 클래스입니다. Math.random은 0.0에서 1.0 사이의 실수 값을 반환하는 정적 헬퍼 함수입니다. 내부적으로 Math.random은 공유되는 단일 Random 인스턴스를 호출합니다.

네, 하지만 동시 호출이 동일한 내부 시드를 두고 경쟁하기 때문에 스레드 기반 코드의 속도가 느려집니다. java.util.concurrent의 ThreadLocalRandom.current()를 사용하여 각 스레드에 자체 생성기를 할당하면 이러한 경쟁을 해결할 수 있습니다.

예를 들어 new Random(42)와 같이 Random 생성자에 고정된 long 값을 전달하거나 setSeed(42)를 호출합니다. 생성기는 실행할 때마다 동일한 시퀀스를 생성하므로 반복 가능한 테스트 및 시뮬레이션에 필수적입니다.

암호, 세션 토큰, 솔트 값, 일회용 코드 및 암호화 키와 같이 예측이 불가능해야 하는 값에는 SecureRandom을 사용하십시오. 일반 난수는 빠르지만 예측 가능하므로 보안 작업에는 적합하지 않습니다.

머신러닝 프레임워크는 의사난수 생성기를 사용하여 가중치를 초기화하고, 훈련 데이터를 섞고, 검증 세트를 분할합니다. 시드를 고정하면 실험의 재현성이 확보되어 팀에서 모델 실행 결과를 비교하고 결과를 안정적으로 디버깅할 수 있습니다.

예. GitHub Copilot은 범위 스케일링 공식과 일치하는 Random, ThreadLocalRandom 및 SecureRandom 코드 조각을 생성합니다. JUnit 테스트. Rev각 제안을 검토하여 선택한 클래스가 사용 사례에 적합한지, 특히 보안에 민감한 코드의 경우 더욱 적합한지 확인하십시오.

이 게시물을 요약하면 다음과 같습니다.