2010-12-25 2 views
16

저는 이것을 약간 혼란스럽게합니다. 임의의 숫자를 생성하기 위해 Random 클래스를 사용할 수 있다는 것을 알고 있지만 8 바이트 숫자를 지정하고 생성하는 방법을 모르겠습니다.Java에서 8 바이트 숫자를 생성하십시오.

감사 부크

답변

13

당신은 java.util.Random 클래스 그렇게 모든 8 바이트 값 (64 비트 시퀀스)이 클래스를 사용하여 생성 할 수없는 48 비트 시드를 사용주의해야 . 이 제한으로 인해이 상황에서 SecureRandomnextBytes method을 사용하는 것이 좋습니다.

사용법은 java.util.Random 솔루션과 매우 비슷합니다. 여기

SecureRandom sr = new SecureRandom(); 
byte[] rndBytes = new byte[8]; 
sr.nextBytes(rndBytes); 

는 48 비트 시드가 충분하지 않은 이유이다

  • Random 클래스는 결정적임을 의미는 의사 난수 발생기를 구현한다.
  • Random의 현재 "상태"가 향후 비트 시퀀스를 결정합니다.
  • 2 개의 상태를 가지므로, 이후의 시퀀스는 2 개 이상일 수 없습니다.
  • 8 바이트 값은 2 가지 가능성이 있으므로 Random 개체에서 이러한 가능성 중 일부를 읽을 수 없습니다. 여기 48 비트 시드를 생성하기위한 솔루션이다 @Peter Lawreys excellent answer 기준

(! 그것은 더 가치가 upvotes). 즉, 가능한 모든 long을 생성 할 수있는 java.util.Random 인스턴스입니다.

class Random96 extends Random { 
    int count = 0; 
    ExposedRandom extra48bits; 

    class ExposedRandom extends Random { 
     public int next(int bits) { // Expose the next-method. 
      return super.next(bits); 
     } 
    } 

    @Override 
    protected int next(int bits) { 
     if (count++ == 0) 
      extra48bits = new ExposedRandom(); 
     return super.next(bits)^extra48bits.next(bits) << 1; 
    } 
} 
+0

모든 답변마다 동일한 댓글을 남겨 두는 것은 좋지 않습니다. – Roman

+2

왜 안 되니? 나는 그것이 괜찮다고 생각한다. 내가 언급 한 각 답변에 적용됩니다. – aioobe

+0

내 직관적 인 솔루션은 2 개의 4 바이트 값을 생성하는 것이 었습니다. 만약 당신이 올바르게 이해한다면, 두 개의 값이 같은 Generator를 두 번 사용할 때 두 값이 동일하지 않게되거나 제외 될 수 있기 때문에 작동하지 않을 것입니다. 예 : FF FF는 FF AA와 유사하지 않습니까? 나는 PRG가 어떻게 구현되는지 알지 못하기 때문에 각 숫자가 이전 수치와 (의사) 독립적 일 것으로 기대하면서 놀랐습니다. – zockman

5
는 길이가 8 바이트 배열하거나 할 수

:

:
byte[] byteArray = new byte[8];  
random.nextBytes(byteArray); 

또는 (8 바이트 수를 나타낸다) 형 long의 변수

long randomLong = random.nextLong(); 
+2

두 가지 대안 모두 모두 가능한 8 바이트 값. 내 대답을 보라. – aioobe

+0

@aioobe : 이유를 설명해 주시겠습니까? 필자는 문서를 읽었으며 구현을 읽었으며 명확한 이해가 아직 없습니다. 다소 복잡한 수학 기반 알고리즘이 있습니다. 이해할 수있는 바와 같이, 종속 값을 생성합니다. 그리고 그것이 사실이라면, 임의의 하나의 인스턴스가 실제로 모든 long 값을 생성하지는 않습니다. 그러나 다른 "랜덤 (Random)"(다른 "시작 지점"과 함께)은 다릅니다. 내가 맞습니까? – Roman

+0

내 대답이 업데이트되었습니다. – aioobe

0

약간의 코드에서 조정 here :

import java.util.Random; 

/** Generate 10 random integers in the range 0..99. */ 
public final class RandomByte { 

    public static final void main(String... aArgs){ 
    log("Generating 10 random integers in range 0..255."); 

    //note a single Random object is reused here 
    Random randomGenerator = new Random(); 
    for (int idx = 1; idx <= 10; ++idx){ 
     int randomInt = randomGenerator.nextInt(256); 
     // int randomInt = randomGenerator.nextBytes(256); 
     log("Generated : " + randomInt); 
    } 

    log("Done."); 
    } 

    private static void log(String aMessage){ 
    System.out.println(aMessage); 
    } 
} 

일부 추가 읽기 : Math.random() versus Random.nextInt(int)

+0

'Random' 클래스는 모든 가능한 8 바이트 값을 생성 할 수 없습니다. – aioobe

2

long 유형은 그래서 Random.nextLong() 당신이 원하는 것을 할 것 같다, 8 바이트의 부호있는 정수입니다. 또는 당신은 결과로 바이트 배열을 필요로하는 경우 :

byte[] result = new byte[8]; 
Random.nextBytes(result); 
+1

'Random' 클래스는 모든 가능한 long을 생성 할 수 없다는 것에 유의하십시오. – aioobe

11

@aioobe '에 대해 동의합니다. 48 비트 시드를 사용하는 랜덤에 동의합니다. SecureRandom은 더 나은 솔루션입니다. 그러나 Random 클래스를 사용하고 가능한 모든 8 바이트 값을 허용하는 방법에 대한 OP의 질문에 대답하려면 주기적으로 시드를 다시 설정해야합니다.

int counter = 0; 
Random rand = new Random(); 
Random rand2 = new Random(); 

if (++counter == 0) rand = new Random(); // reset every 4 billion values. 

long randomLong = rand.nextLong()^rand2.nextLong() << 1; 

임의로 2^47 long 값의 시퀀스 만 허용합니다. 2 개의 랜덤 제네레이터 (순서대로 계속 뛰어 넘음)를 사용하면 2^47 * 2^47 개의 가능한 값을 얻을 수 있습니다. < < 1을 사용하면 동일한 시드가있는 두 랜덤을 가질 때의 영향을 피할 수 있습니다 (이 경우 ^는 한 행에 40 억 개의 값에 대해 0을 생성합니다)

+0

+1, 좋은 답변입니다. 리셋 및 교대에 관한 흥미로운 메모 - 왼쪽! Random의 익명 하위 클래스에 Random 인스턴스를 캡슐화하면 더 나은 대답을 원합니다. – aioobe

+0

2 개의 무작위 오브젝트가 동일한 시드를 갖기 때문에 정확히 같은 난수를 생성하지 않습니까? (즉, 빠른 컴퓨터에서 System.currentTimeMillis()는 둘 다 동일하게됩니까?) –

+0

Java의 이전 버전에서 true입니다. Java 5.0에서 Random은 System.nanoTime()과 AtomicLong 카운터를 사용합니다. –

관련 문제