임의 문자열을 사용하는이 코드가 "hello world"를 인쇄하는 이유는 무엇입니까?


1769

다음 인쇄 문은 "hello world"를 인쇄합니다. 누구든지 이것을 설명 할 수 있습니까?

System.out.println(randomString(-229985452) + " " + randomString(-147909649));

그리고 이것 randomString()처럼 보입니다 :

public static String randomString(int i)
{
    Random ran = new Random(i);
    StringBuilder sb = new StringBuilder();
    while (true)
    {
        int k = ran.nextInt(27);
        if (k == 0)
            break;

        sb.append((char)('`' + k));
    }

    return sb.toString();
}

158
글쎄, 그 특정 씨앗은 완벽하게 작동합니다. 무작위는 실제로 무작위가 아니라 의사 난수입니다.
Doorknob

341
무작위가 아니기 때문에 다른 사람들이 말했듯이 작동합니다. 나에게 더 흥미로운 질문은 그것을 쓴 사람이 그것을 강요하거나 주어진 씨앗에 대해 다음 N 값에 대해 무작위가 생성되는 것을 예측하는 쉬운 방법이 있습니까? 무차별 강제는 쉽고 하드웨어가 오래 걸리지 않기 때문에 실행하는 것이 가능합니다. 정적이기 때문에 네트워크를 통해 검색을 쉽게 배포 할 수도 있습니다.
jmoreno

78
나는의 목적 의문 n의를 for (int n = 0; ; n++). 그들은 for(;;)또는 while(true)대신 사용할 수 있습니다 !
Eng.Fouad

13
실제로 임의의 순서로 가능한 모든 문자열이 나타납니다. 고품질의 의사 랜덤 시퀀스에서 가능한 모든 길이의 문자열 (log_s (N)-n) 비트를 합리적으로 기대할 수 있습니다 (여기서 N은 PRNGs 내부 상태의 비트 수이고 n은 작은 수입니다) )를 사이클에 표시합니다. 이 코드는 거의 전체 8 비트를 다시 가져 오는 자유롭게 선택된 하드 코딩 된 시작점 (문자 백틱 값)을 사용하여 도움을받습니다.
dmckee --- 전 운영자 고양이

13
이것은 몇 년 전에 쓴 글에서 나온 것입니다. vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
피터로 레이

답변:


917

의 인스턴스가 java.util.Random특정 시드 매개 변수 (이 경우 -229985452또는 -147909649) 로 구성된 경우 해당 시드 값으로 시작 하는 난수 생성 알고리즘을 따릅니다 .

Random동일한 시드로 구성된 모든 항목은 매번 동일한 패턴의 숫자를 생성합니다.


8
@Vulcan-javadoc은 시드가 48 비트라고 말합니다. docs.oracle.com/javase/7/docs/api/java/util/Random.html . 또한 실제 시드는 32 비트 값입니다.
Stephen C

80
난수 시퀀스의 각 요소 (27)는 모듈로 촬영하고, 각각의 6 개 개의 요소가 존재 "hello\0"하고 "world\0". 정말로 무작위 생성기를 가정했다면 27 ^ 6 (387,420,489)에서 1이 될 것입니다. 따라서 시퀀스가 ​​인상적입니다.
Russell Borogove

17
@RussellBorogove : 그러나 그 가능성과 2 ^ 64 개의 가능한 시드로, 그 시퀀스를 제공 할 것으로 예상되는 시드 값은 470 억입니다. 하나를 찾는 것의 문제 일뿐입니다.
dan04

8
@ dan04-나는 그 견적을 내릴 의향이 없었습니다. PRNG의 구현에 따라 시드 워드의 크기가 상태의 크기와 같지 않을 수 있으며 시퀀스 경로가 고르게 분산되지 않을 수 있습니다. 그러나 여전히, 확률은 확실히 좋으며, 만약 당신이 짝을 찾을 수 없다면 다른 케이싱 ( "Hello" "World")으로 다시 시도 하거나, 또는 122-k대신에 다시 시도 할 수 있습니다 96+k.
Russell Borogove

7
@ ThorbjørnRavnAndersen Javadoc 은 "특정 알고리즘은 Random 클래스에 대해 지정됩니다. Java 구현은 Java 코드의 절대 이식성을 위해 Random 클래스에 대해 여기에 표시된 모든 알고리즘을 사용해야합니다."
FThompson

1137

다른 답변은 이유를 설명하지만 여기에 방법이 있습니다.

주어진 인스턴스 Random:

Random r = new Random(-229985452)

r.nextInt(27)생성 되는 처음 6 개의 숫자 는 다음과 같습니다.

8
5
12
12
15
0

r.nextInt(27)주어진 6 개의 숫자 는 다음 Random r = new Random(-147909649)과 같습니다.

23
15
18
12
4
0

그런 다음 숫자를 문자의 정수 표현에 추가하십시오 `(96).

8  + 96 = 104 --> h
5  + 96 = 101 --> e
12 + 96 = 108 --> l
12 + 96 = 108 --> l
15 + 96 = 111 --> o

23 + 96 = 119 --> w
15 + 96 = 111 --> o
18 + 96 = 114 --> r
12 + 96 = 108 --> l
4  + 96 = 100 --> d

48
Pedantically, new Random(-229985452).nextInt(27)항상 8. 반환
user253751

1
@immibis 왜? 난 Random ()은 수정 순서가 설정된 숫자가 아닌 매번 난수를 반환해야한다는 것을 의미합니까?
roottraveller

5
@rootTraveller 처음 new Random()에는 숫자를 전혀 반환하지 않습니다.
user253751

2
이 씨앗을 계산하는 방법이 있습니까? 어떤 논리가 있어야합니다.
Sohit Gore

2
@SohitGore Java의 기본값 Random이 암호로 안전하지 않다는 것을 감안할 때 (메르 센 트위스터라고 확신하지만 그에 대해 인용하지는 마십시오) "이 숫자를 원합니다"에서 "이것은 씨앗을 사용하겠습니다. " 표준 C 선형 합동 생성기와 비슷한 작업을 수행했습니다.
Fund Monica의 소송

280

그냥 여기 두겠습니다 여유가 많은 (CPU) 시간을 가진 사람은 자유롭게 실험 해보십시오. 귀하의 코드. 대단히 감사하겠습니다.

public static void main(String[] args) {
    long time = System.currentTimeMillis();
    generate("stack");
    generate("over");
    generate("flow");
    generate("rulez");

    System.out.println("Took " + (System.currentTimeMillis() - time) + " ms");
}

private static void generate(String goal) {
    long[] seed = generateSeed(goal, Long.MIN_VALUE, Long.MAX_VALUE);
    System.out.println(seed[0]);
    System.out.println(randomString(seed[0], (char) seed[1]));
}

public static long[] generateSeed(String goal, long start, long finish) {
    char[] input = goal.toCharArray();
    char[] pool = new char[input.length];
    label:
    for (long seed = start; seed < finish; seed++) {
        Random random = new Random(seed);

        for (int i = 0; i < input.length; i++)
            pool[i] = (char) random.nextInt(27);

        if (random.nextInt(27) == 0) {
            int base = input[0] - pool[0];
            for (int i = 1; i < input.length; i++) {
                if (input[i] - pool[i] != base)
                    continue label;
            }
            return new long[]{seed, base};
        }

    }

    throw new NoSuchElementException("Sorry :/");
}

public static String randomString(long i, char base) {
    System.out.println("Using base: '" + base + "'");
    Random ran = new Random(i);
    StringBuilder sb = new StringBuilder();
    for (int n = 0; ; n++) {
        int k = ran.nextInt(27);
        if (k == 0)
            break;

        sb.append((char) (base + k));
    }

    return sb.toString();
}

산출:

-9223372036808280701
Using base: 'Z'
stack
-9223372036853943469
Using base: 'b'
over
-9223372036852834412
Using base: 'e'
flow
-9223372036838149518
Using base: 'd'
rulez
Took 7087 ms

24
@OneTwoThree nextInt(27)는 범위 내에 있음을 의미합니다 [0, 26].
Eng.Fouad

30
@Vulcan 1에서 1000 사이의 임의의 숫자를 선택하는 것처럼 대부분의 시드는 최대 값에 매우 가깝습니다. 당신이 그것에 대해 생각할 때 그것은 놀라운 일이 아닙니다 :)
Thomas

18
@Vulcan 실제로 수학을 수행하면 최대 값에 거의 0에 가깝다는 것을 알 수 있습니다 (시드가 생성 코드에서 부호없는 것으로 해석되는 것으로 가정합니다). 그러나 자릿수가 실제 값과 함께 대수적으로 만 증가하기 때문에 실제로는 그렇지 않을 때 숫자가 매우 가깝게 보입니다.
Thomas

10
좋은 대답입니다. 보너스 포인트의 경우 랜덤을 초기화하여 최종 랜덤을 초기화하는 데 필요한 4 개의 시드 시퀀스를 생성하는 시드를 찾을 수 있습니까?
Marek

13
@Marek : 의사 랜덤의 신들이 그런 행동을 승인하지 않을 것이라고 생각합니다.
Denis Tulskiy

254

여기의 모든 사람들은 코드의 작동 방식을 설명하고 자신의 예제를 구성 할 수있는 방법을 보여주는 훌륭한 작업을 수행했지만, 무차별 대입 검색이 결국에는 찾게 될 솔루션이 합리적으로 예상되는 이유를 보여주는 정보 이론적 답변이 있습니다.

26 개의 소문자가 알파벳을 형성합니다 Σ. 길이가 다른 단어를 생성 할 수 있도록 확장 알파벳을 만들기 위해 종료 기호 를 추가합니다 Σ' := Σ ∪ {⊥}.

α대해 균일하게 분포 된 랜덤 변수 인 기호와 X를 사용합니다 Σ'. 해당 기호 P(X = α)및 해당 정보 내용 을 얻을 수있는 확률 I(α)은 다음과 같습니다.

P (X = α) = 1 / | Σ '| = 1/27

I (α) = -log₂ [P (X = α)] = -log₂ (1/27) = 로그 ₂ (27)

단어 ω ∈ Σ*와 그에 ⊥-대응 하는 단어의 ω' := ω · ⊥ ∈ (Σ')*경우

I (ω) : = I (ω ') = | ω'| * log₂ (27) = (| ω | + 1) * log₂ (27)

PRNG (Pseudorandom Number Generator)는 32 비트 시드로 초기화되므로 대부분의 단어 길이는 최대

λ = 층 [32 / log₂ (27)]-1 = 5

적어도 하나의 시드에 의해 생성됩니다. 6 자 단어를 검색하더라도 약 41.06 %의 시간이 성공할 것입니다. 너무 초라하지 않습니다.

7 글자의 경우 1.52 %에 가깝지만 시도해보기 전에이를 알지 못했습니다.

#include <iostream>
#include <random>

int main()
{
    std::mt19937 rng(631647094);
    std::uniform_int_distribution<char> dist('a', 'z' + 1);

    char alpha;
    while ((alpha = dist(rng)) != 'z' + 1)
    {
        std::cout << alpha;
    }
}

출력을 참조하십시오 : http://ideone.com/JRGb3l


내 정보 이론은 다소 약하지만이 증거를 좋아합니다. 누군가 람다 선을 설명 할 수 있습니까? 분명히 우리는 서로의 정보 내용을 서로 나누고 있지만 왜 우리에게 단어 길이를 제공합니까? 내가 말했듯이 나는 명백한 것을 요구하는 것에 대해 약간의 녹슨 사과입니다 (NB는 코드 출력에서 ​​shannon 한계와 관련이 있습니다)
Mike HR

1
@ MikeH-R 람다 라인은 I(⍵)재 배열 된 방정식입니다. I(⍵)32 (비트)이고 |⍵|5 (기호)로 밝혀졌습니다.
iceman

67

이 씨앗을 찾기위한 빠른 프로그램을 작성했습니다.

import java.lang.*;
import java.util.*;
import java.io.*;

public class RandomWords {
    public static void main (String[] args) {
        Set<String> wordSet = new HashSet<String>();
        String fileName = (args.length > 0 ? args[0] : "/usr/share/dict/words");
        readWordMap(wordSet, fileName);
        System.err.println(wordSet.size() + " words read.");
        findRandomWords(wordSet);
    }

    private static void readWordMap (Set<String> wordSet, String fileName) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(fileName));
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim().toLowerCase();
                if (isLowerAlpha(line)) wordSet.add(line);
            }
        }
        catch (IOException e) {
            System.err.println("Error reading from " + fileName + ": " + e);
        }
    }

    private static boolean isLowerAlpha (String word) {
        char[] c = word.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] < 'a' || c[i] > 'z') return false;
        }
        return true;
    }

    private static void findRandomWords (Set<String> wordSet) {
        char[] c = new char[256];
        Random r = new Random();
        for (long seed0 = 0; seed0 >= 0; seed0++) {
            for (int sign = -1; sign <= 1; sign += 2) {
                long seed = seed0 * sign;
                r.setSeed(seed);
                int i;
                for (i = 0; i < c.length; i++) {
                    int n = r.nextInt(27);
                    if (n == 0) break;
                    c[i] = (char)((int)'a' + n - 1);
                }
                String s = new String(c, 0, i);
                if (wordSet.contains(s)) {
                    System.out.println(s + ": " + seed);
                    wordSet.remove(s);
                }
            }
        }
    }
}

지금 백그라운드에서 실행 중이지만 이미 클래식 팬 그램에 충분한 단어가 있습니다.

import java.lang.*;
import java.util.*;

public class RandomWordsTest {
    public static void main (String[] args) {
        long[] a = {-73, -157512326, -112386651, 71425, -104434815,
                    -128911, -88019, -7691161, 1115727};
        for (int i = 0; i < a.length; i++) {
            Random r = new Random(a[i]);
            StringBuilder sb = new StringBuilder();
            int n;
            while ((n = r.nextInt(27)) > 0) sb.append((char)('`' + n));
            System.out.println(sb);
        }
    }
}

( 아이디 온 데모 )

추신. -727295876, -128911, -1611659, -235516779.


35

나는 이것에 흥미를 느꼈다. 나는이 임의의 단어 생성기를 사전 단어 목록에서 실행했다. 범위 : 정수 .MIN_VALUE에서 정수 .MAX_VALUE

나는 15131 안타를 얻었다.

int[] arrInt = {-2146926310, -1885533740, -274140519, 
                -2145247212, -1845077092, -2143584283,
                -2147483454, -2138225126, -2147375969};

for(int seed : arrInt){
    System.out.print(randomString(seed) + " ");
}

인쇄물

the quick browny fox jumps over a lazy dog 

7
당신은 내 하루 남자를 만들었습니다 : DI는 Long.Min / Max로 그것을 시도하고 내 동료의 이름을 검색하고 피터 만 찾았습니다 : (peter 4611686018451441623 peter 24053719 peter -4611686018403334185 peter -9223372036830722089 peter -4611686017906248127 peter 521139777 peter 4611686018948527681 peter -9223372036333636031 peter- 4611686017645756173 피터 781631731 피터 4611686019209019635 피터 -9223372036073144077 피터 -4611686017420317288 피터 1007070616 피터 -9223372035847705192)
Marcel

25

대부분의 난수 생성기는 실제로 "의사 난수"입니다. 선형 일치 생성기 또는 LCG입니다 ( http://en.wikipedia.org/wiki/Linear_congruential_generator ).

LCG는 고정 된 시드가 주어지면 상당히 예측 가능합니다. 기본적으로 첫 번째 문자를 제공하는 시드를 사용하고 대상 문자열에서 다음 문자를 칠 때까지 다음 int (char)를 계속 생성하는 앱을 작성하고 LCG를 호출 해야하는 횟수를 적어 두십시오. 각각의 모든 문자를 생성 할 때까지 계속하십시오.


3
의사가 아닌 난수 생성기의 예
chiliNUT

1
@chiliNUT 이러한 생성기는 외부 장치입니다. 일부 전자 램프. 또는 0 또는 1로 읽히는 잘못 작성된 비트. 순수의 순수 디지털 생성기를 수행 할 수 없으며 디지털 알고리즘은 임의적이지 않으며 절대적으로 정확합니다.
Gangnus

@chiliNUT 많은 운영 체제가 엔트로피를 수집 합니다 . 예를 들어 Linux에서는 /dev/urandom장치를 사용하여 임의의 데이터를 읽을 수 있습니다 . 그러나 이것은 희소 한 자원이다. 따라서 이러한 임의의 데이터는 일반적으로 PRNG를 시드하는 데 사용됩니다.
Adrian W

@AdrianW Wikipedia에 따르면 urandom여전히 의사 랜덤입니다. en.wikipedia.org/wiki//dev/random
chiliNUT

1
예, 그러나 암호로 안전합니다. 즉,에서 생성 된 임의의 시퀀스로 무차별 대입 공격 ( "무작위"시퀀스 "hello world"에 대한 시드 찾기)을 수행 할 수 없습니다 /dev/random. 위에서 인용 한 기사에 따르면 Linux 커널은 키보드 타이밍, 마우스 이동 및 IDE 타이밍에서 엔트로피를 생성하고 특수 파일 / dev / random 및 / dev / urandom을 통해 다른 운영 체제 프로세스에서 임의의 문자 데이터를 사용할 수 있습니다. 그건 정말 무작위라고 믿게 해주었습니다. 완전히 정확하지 않을 수 있습니다. 그러나 /dev/random최소한 엔트로피 가 포함되어 있습니다 .
Adrian W

23

Java를 사용하면 멀티 스레딩이 매우 쉬워 지므로 다음은 사용 가능한 모든 코어를 사용하여 시드를 검색하는 변형입니다. http://ideone.com/ROhmTA

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class SeedFinder {

  static class SearchTask implements Callable<Long> {

    private final char[] goal;
    private final long start, step;

    public SearchTask(final String goal, final long offset, final long step) {
      final char[] goalAsArray = goal.toCharArray();
      this.goal = new char[goalAsArray.length + 1];
      System.arraycopy(goalAsArray, 0, this.goal, 0, goalAsArray.length);
      this.start = Long.MIN_VALUE + offset;
      this.step = step;
    }

    @Override
    public Long call() throws Exception {
      final long LIMIT = Long.MAX_VALUE - this.step;
      final Random random = new Random();
      int position, rnd;
      long seed = this.start;

      while ((Thread.interrupted() == false) && (seed < LIMIT)) {
        random.setSeed(seed);
        position = 0;
        rnd = random.nextInt(27);
        while (((rnd == 0) && (this.goal[position] == 0))
                || ((char) ('`' + rnd) == this.goal[position])) {
          ++position;
          if (position == this.goal.length) {
            return seed;
          }
          rnd = random.nextInt(27);
        }
        seed += this.step;
      }

      throw new Exception("No match found");
    }
  }

  public static void main(String[] args) {
    final String GOAL = "hello".toLowerCase();
    final int NUM_CORES = Runtime.getRuntime().availableProcessors();

    final ArrayList<SearchTask> tasks = new ArrayList<>(NUM_CORES);
    for (int i = 0; i < NUM_CORES; ++i) {
      tasks.add(new SearchTask(GOAL, i, NUM_CORES));
    }

    final ExecutorService executor = Executors.newFixedThreadPool(NUM_CORES, new ThreadFactory() {

      @Override
      public Thread newThread(Runnable r) {
        final Thread result = new Thread(r);
        result.setPriority(Thread.MIN_PRIORITY); // make sure we do not block more important tasks
        result.setDaemon(false);
        return result;
      }
    });
    try {
      final Long result = executor.invokeAny(tasks);
      System.out.println("Seed for \"" + GOAL + "\" found: " + result);
    } catch (Exception ex) {
      System.err.println("Calculation failed: " + ex);
    } finally {
      executor.shutdownNow();
    }
  }
}

나 같은 자바 멍청한 놈에, 당신과 함께 출력 번호 접미사 필요 L와의 인수 유형 변경 long, 즉 randomString(long i)주위를 재생하려면. :)
과일

21

랜덤은 항상 같은 시퀀스를 반환합니다. 배열과 다른 연산을 순열로 섞는 데 사용됩니다.

다른 시퀀스를 얻으려면 "seed"라는 특정 위치에서 시퀀스를 초기화해야합니다.

randomSting은 "random"시퀀스의 i 위치 (seed = -229985452)에있는 난수를 가져옵니다. 그런 다음이 값이 0이 될 때까지 시드 위치 뒤의 순서에서 다음 27 자에 ASCII 코드를 사용합니다 . "hello"가 반환됩니다. "world"에 대해서도 동일한 작업이 수행됩니다.

다른 코드에서는 코드가 작동하지 않았다고 생각합니다. 프로그래밍 한 사람은 무작위 순서를 잘 알고 있습니다.

매우 훌륭한 괴짜 코드입니다!


10
그가 "임의의 순서를 잘 알고 있는지"의심 스럽다. 아마도 그는 효과가있는 씨앗을 찾을 때까지 수십억 개의 가능한 씨앗을 시도했을 것입니다.
dan04

24
@ dan04 실제 프로그래머는 단순히 PRNG를 사용하는 것이 아니라 전체 기간을 기억하고 필요에 따라 값을 열거합니다.
Thomas

1
"랜덤은 항상 같은 순서를 반환합니다"-임의의 뒤에 ()를 넣거나 코드로 표시하십시오. 그렇지 않으면 문장이 거짓입니다.
Gangnus

14

교장은 동일한 시드로 구성된 랜덤 클래스는 매번 동일한 패턴의 숫자를 생성합니다.


12

Denis Tulskiy 의 답변 에서 파생 된 이 방법은 시드를 생성합니다.

public static long generateSeed(String goal, long start, long finish) {
    char[] input = goal.toCharArray();
    char[] pool = new char[input.length];
    label:
        for (long seed = start; seed < finish; seed++) {
            Random random = new Random(seed);

            for (int i = 0; i < input.length; i++)
                pool[i] = (char) (random.nextInt(27)+'`');

            if (random.nextInt(27) == 0) {
                for (int i = 0; i < input.length; i++) {
                    if (input[i] != pool[i])
                        continue label;
                }
                return seed;
            }

        }

    throw new NoSuchElementException("Sorry :/");
}

10

Java 문서에서 Random 클래스의 시드 값을 지정할 때 의도적 인 기능입니다.

동일한 시드로 두 개의 Random 인스턴스가 작성되고 각각에 대해 동일한 시퀀스의 메소드 호출이 수행되면 동일한 시퀀스의 숫자를 생성하고 리턴합니다. 이 속성을 보장하기 위해 Random 클래스에 특정 알고리즘이 지정됩니다. Java 구현은 Java 코드의 절대 이식성을 위해 Random 클래스에 대해 여기에 표시된 모든 알고리즘을 사용해야합니다.

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html

그러나 예측 가능한 '무작위'숫자를 갖는 데 암시적인 보안 문제가 있다고 생각할 것입니다.


3
그렇기 때문에 기본 생성자가 Random"난수 생성기의 시드를이 생성자의 다른 호출과 구별 될 수있는 값으로 설정합니다"( javadoc )입니다. 현재 구현에서 이것은 현재 시간과 카운터의 조합입니다.
martin mar

과연. 아마도 초기 시드 값을 지정하기위한 실제 사용 사례가있을 것입니다. 나는 그것이 당신이 얻을 수있는 의사 난수 키
포브

4
@ deed02392 물론 시드 값을 지정하기위한 실제 사용 사례가 있습니다. 문제를 해결하기 위해 일종의 몬테 카를로 접근 방식을 사용하기 위해 데이터를 시뮬레이션하는 경우 결과를 재현하는 것이 좋습니다. 초기 시드를 설정하는 것이 가장 쉬운 방법입니다.
Dason


3

Denis Tulskiy의 대답 이 약간 개선되었습니다 . 시간을 반으로 줄입니다

public static long[] generateSeed(String goal, long start, long finish) {
    char[] input = goal.toCharArray();

    int[] dif = new int[input.length - 1];
    for (int i = 1; i < input.length; i++) {
        dif[i - 1] = input[i] - input[i - 1];
    }

    mainLoop:
    for (long seed = start; seed < finish; seed++) {
        Random random = new Random(seed);
        int lastChar = random.nextInt(27);
        int base = input[0] - lastChar;
        for (int d : dif) {
            int nextChar = random.nextInt(27);
            if (nextChar - lastChar != d) {
                continue mainLoop;
            }
            lastChar = nextChar;
        }
        if(random.nextInt(27) == 0){
            return new long[]{seed, base};
        }
    }

    throw new NoSuchElementException("Sorry :/");
}

1

입력 seed 에 관한 모든 것 입니다. 동일한 씨앗은 항상 동일한 결과를 제공합니다. 프로그램을 반복해서 다시 실행하더라도 동일한 출력입니다.

public static void main(String[] args) {

    randomString(-229985452);
    System.out.println("------------");
    randomString(-229985452);

}

private static void randomString(int i) {
    Random ran = new Random(i);
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());
    System.out.println(ran.nextInt());

}

산출

-755142161
-1073255141
-369383326
1592674620
-1524828502
------------
-755142161
-1073255141
-369383326
1592674620
-1524828502
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.