Dlaczego ten kod za pomocą losowych ciągów wypisuje „hello world”?


1769

Poniższa instrukcja print wyświetli „hello world”. Czy ktoś mógłby to wyjaśnić?

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

I randomString()wygląda tak:

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
Cóż, te konkretne nasiona tak się po prostu doskonale sprawdzają. Losowość nie jest tak naprawdę losowa, jest pseudolosowa.
Klamka

341
Działa, jak powiedzieli inni, ponieważ losowość nie jest. Dla mnie bardziej interesujące byłoby pytanie, czy osoba, która to napisała, brutalnie ją wymusiła, czy też istnieje prosty sposób przewidzieć, co losowo wygeneruje dla następnych N wartości dla danego ziarna. Brutalne wymuszanie jest łatwe, a przy nowoczesnym sprzęcie nie powinno to zająć zbyt długo, więc nie było wątpliwości, że jest to realne. Biorąc pod uwagę, że jest statyczny, możesz nawet z łatwością rozdzielić wyszukiwanie w sieci.
jmoreno

78
Zastanawiam cel nw for (int n = 0; ; n++). Mogą użyć for(;;)lub while(true)zamiast!
Eng.Fouad

13
W naprawdę losowej sekwencji w końcu pojawią się wszystkie możliwe łańcuchy. W wysokiej jakości pseudolosowej sekwencji można rozsądnie oczekiwać każdego możliwego ciągu długości (log_s (N) - n) bitów (gdzie N jest liczbą bitów w stanie wewnętrznym PRNG, a n jest małą liczbą, dla wygody wybierz 8 ) do pojawienia się w cyklu. Ten kod uzyskuje pewną pomoc z wykorzystaniem dowolnie wybranego punktu początkowego (wartość znaku wstecznego), który odzyskuje prawie całe 8 bitów.
dmckee --- były moderator kociąt

13
To z postu, który napisałem kilka lat temu. vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
Peter Lawrey

Odpowiedzi:


917

Gdy instancja java.util.Randomjest konstruowana z określonym parametrem początkowym (w tym przypadku -229985452lub -147909649), postępuje zgodnie z algorytmem generowania liczb losowych rozpoczynającym się od tej wartości początkowej .

Każde Randomzbudowane z tego samego materiału siewnego będzie generować ten sam wzór liczb za każdym razem.


8
@Vulcan - javadoc mówi, że ziarno ma 48 bitów. docs.oracle.com/javase/7/docs/api/java/util/Random.html . Poza tym rzeczywiste nasiona to 32-bitowe wartości.
Stephen C

80
Każdy element liczb losowych rozpuszcza modulo 27 i jest 6 elementy każdego "hello\0"a "world\0". Jeśli wybierzesz naprawdę losowy generator, szanse będą wynosić 1 na 27 ^ 6 (387,420,489) uzyskania sekwencji, której szukasz - więc jest to dość imponujące, ale nie zadziwiające!
Russell Borogove

17
@ RussellBorogove: Ale przy tych szansach i 2 ^ 64 możliwych nasionach, oczekuje się 47,6 miliarda wartości nasion, które dają tę sekwencję. To tylko kwestia znalezienia jednego.
dan04

8
@ dan04 - Nie byłem skłonny dokonać takiej oceny; w zależności od implementacji PRNG rozmiar słowa początkowego może nie być równy rozmiarowi stanu, a ścieżki sekwencji mogą nie być równomiernie rozłożone. Ale nadal szanse są zdecydowanie dobre, a jeśli nie możesz znaleźć pary, możesz spróbować ponownie z inną obudową ( "Hello" "World") lub używając 122-kzamiast 96+k, lub ...
Russell Borogove

7
@ ThorbjørnRavnAndersen Javadoc określa, że ​​„określone algorytmy są określone dla klasy Losowo. Implementacje Java muszą używać wszystkich przedstawionych tu algorytmów dla klasy Losowo, ze względu na absolutną przenośność kodu Java”.
FThompson

1137

Inne odpowiedzi wyjaśniają dlaczego, ale oto jak.

Biorąc pod uwagę przykład Random:

Random r = new Random(-229985452)

Pierwsze 6 liczb, które r.nextInt(27)generuje to:

8
5
12
12
15
0

a pierwsze 6 liczb, które r.nextInt(27)generuje podane Random r = new Random(-147909649)to:

23
15
18
12
4
0

Następnie po prostu dodaj te liczby do reprezentacji liczb całkowitych znaku `(czyli 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
Pedantycznie new Random(-229985452).nextInt(27)zawsze zwraca 8.
253751

1
@immibis dlaczego? mam na myśli, że Random () powinien zwracać losową liczbę za każdym razem, a nie ustalony numer porządkowy?
roottraveller

5
@rootTraveller Na początek new Random()nie zwraca wcale liczby.
user253751,

2
Czy istnieje sposób obliczenia tych nasion? Musi być jakaś logika ... czy to tylko brutalna siła.
Sohit Gore

2
@SohitGore Biorąc pod uwagę, że domyślna Java Randomnie jest kryptograficznie bezpieczna (jestem prawie pewna, że ​​to Mersenne Twister, ale nie cytuj mnie), prawdopodobnie możliwe jest przejście wstecz od „Chcę te liczby” do „to jest seed użyłbym ". Zrobiłem coś podobnego ze standardowym liniowym generatorem kongruencjalnym C.
Pozew funduszu Moniki

280

Zostawię to tutaj. Ktokolwiek ma dużo czasu (procesora) do stracenia, nie krępuj się eksperymentować :) Ponadto, jeśli opanowałeś rozwidlenie, aby spalić wszystkie rdzenie procesora (tylko wątki są nudne, prawda?), Udostępnij Twój kod. Byłbym bardzo wdzięczny.

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();
}

Wynik:

-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)oznacza w zasięgu [0, 26].
Eng. Fouad

30
@ Vulcan Większość nasion jest bardzo zbliżona do maksymalnej wartości, podobnie jak w przypadku losowych liczb od 1 do 1000, większość liczb, które wybierzesz, będzie miała trzy cyfry. Nic dziwnego, kiedy się nad tym zastanowić :)
Thomas

18
@Vulcan W rzeczywistości, jeśli wykonasz matematykę, zobaczysz, że są one zbliżone do wartości maksymalnej równej zeru (przypuszczam, że ziarno jest interpretowane jako niepodpisane w kodzie generacyjnym). Ale ponieważ liczba cyfr rośnie tylko logarytmicznie z rzeczywistą wartością, liczba wydaje się bardzo bliska, gdy tak naprawdę nie jest.
Thomas

10
Świetna odpowiedź. A jeśli chodzi o punkty bonusowe, czy możesz znaleźć ziarno, które zainicjuje Losowo, co wytworzy sekwencję 4 nasion wymaganych do zainicjowania ostatecznych losowych?
Marek

13
@Marek: Nie sądzę, aby bogowie pseudolosowi zaakceptowali takie zachowanie.
Denis Tulskiy,

254

Wszyscy tutaj wykonali świetną robotę, wyjaśniając, jak działa kod i pokazując, jak można konstruować własne przykłady, ale oto teoretyczna odpowiedź informacyjna pokazująca, dlaczego możemy słusznie oczekiwać rozwiązania, które w końcu znajdzie brutalne wyszukiwanie.

26 różnych małych liter tworzy nasz alfabet Σ. Aby umożliwić generowanie słów o różnych długościach, dodajemy dodatkowo symbol terminatora, aby uzyskać rozszerzony alfabet Σ' := Σ ∪ {⊥}.

Niech αbędzie symbolem, a X równomiernie rozmieszczoną zmienną losową Σ'. Prawdopodobieństwo uzyskania tego symbolu P(X = α)oraz jego zawartości informacyjnej I(α)są określone przez:

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

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

Dla słowa ω ∈ Σ*i jego ⊥-zakończonego odpowiednika ω' := ω · ⊥ ∈ (Σ')*mamy

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

Ponieważ Generator liczb pseudolosowych (PRNG) jest inicjowany za pomocą 32-bitowego materiału źródłowego, możemy spodziewać się większości słów o długości do

λ = piętro [32 / log₂ (27)] - 1 = 5

do wygenerowania przez co najmniej jedno ziarno. Nawet gdybyśmy szukali słowa składającego się z 6 znaków, nadal odnosilibyśmy sukces przez około 41,06% czasu. Nieźle.

W przypadku 7 liter przyglądamy się bliżej 1,52%, ale nie zdawałem sobie z tego sprawy, zanim spróbowałem:

#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;
    }
}

Zobacz wynik: http://ideone.com/JRGb3l


moja teoria informacji jest trochę słaba, ale uwielbiam ten dowód. czy ktoś może mi wyjaśnić linię lambda, wyraźnie dzielimy zawartość informacyjną jednego z drugim, ale dlaczego daje to nam długość słowa? jak powiedziałem, jestem trochę zardzewiały, więc przepraszam, że pytam o oczywiste (uwaga: czy to ma coś wspólnego z limitem Shannona - z kodu wyjściowego)
Mike HR

1
@ MikeH-R Linia lambda jest I(⍵)uporządkowanym równaniem. I(⍵)ma 32 (bitów) i |⍵|okazuje się być 5 (symbolami).
lodowiec

67

Napisałem szybki program do znalezienia tych nasion:

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);
                }
            }
        }
    }
}

Mam go teraz uruchomionego w tle, ale znalazłem już wystarczająco dużo słów na klasyczny pangram:

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);
        }
    }
}

( Demo na ideone. )

Ps. -727295876, -128911, -1611659, -235516779.


35

Byłem tym zaintrygowany, uruchomiłem ten generator losowych słów na liście słów w słowniku. Zakres: Integer.MIN_VALUE do Integer.MAX_VALUE

Mam 15131 trafień.

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

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

Wydruki

the quick browny fox jumps over a lazy dog 

7
Sprawiłeś, że mój dzień: DI wypróbowałem to z Long.Min / Max i poszukałem imion moich kolegów i znalazłem tylko Petera: (peter 4611686018451441623 peter 24053719 peter -4611686018403334185 peter -9223372036830722089 peter -4611686017906248127 peter 5211396818 4611686017645756173 Peter 781631731 Peter 4611686019209019635 Peter -9223372036073144077 Peter -4611686017420317288 Peter 1007070616 Peter -9223372035847705192)
Marcel

25

Większość generatorów liczb losowych jest w rzeczywistości „pseudolosowymi”. Są to liniowe generatory conruential lub LCG ( http://en.wikipedia.org/wiki/Linear_congruential_generator )

LCG są dość przewidywalne, biorąc pod uwagę ustalone nasiona. Zasadniczo użyj zarodka, który daje ci pierwszą literę, a następnie napisz aplikację, która generuje następne int (char), aż trafisz następną literę w docelowym ciągu i zapisz, ile razy trzeba było wywoływać LCG. Kontynuuj, aż wygenerujesz każdą literę.


3
jaki jest przykład generatora liczb
niepseudolosowych

1
@chiliNUT Takie generatory to zewnętrzne gadżety. Jakaś lampa elektroniczna. Lub źle napisany bit, który jest odczytywany 0 lub 1. Nie można zrobić czystego cyfrowego generatora liczb losowych, algorytmy cyfrowe NIE są losowe, są absolutnie precyzyjne.
Gangnus,

@chiliNUT Wiele systemów operacyjnych zbiera entropię . Np. W systemie Linux możesz użyć /dev/urandomurządzenia do odczytu losowych danych. Jest to jednak rzadki zasób. Tak więc takie losowe dane są zwykle wykorzystywane do inicjowania PRNG.
Adrian W

@AdrianW Wikipedia twierdzi, że urandomwciąż jest pseudolosowo pl.wikipedia.org/wiki//dev/random
chiliNUT

1
Tak, ale jest kryptograficznie bezpieczny, co oznacza, że ​​nie można wykonywać brutalnych ataków (jak znaleźć ziarno dla „losowej” sekwencji „witaj świecie”) z losowymi sekwencjami utworzonymi /dev/random. Artykuł, który cytowałem powyżej, mówi, że jądro Linux generuje entropię na podstawie czasów klawiatury, ruchów myszy i czasów IDE oraz udostępnia dane losowych znaków innym procesom systemu operacyjnego poprzez specjalne pliki / dev / random i / dev / urandom. To pozwala mi wierzyć, że to naprawdę przypadek. Być może nie jest to w pełni poprawne. Ale /dev/randomprzynajmniej zawiera trochę entropii.
Adrian W

23

Ponieważ wielowątkowość jest bardzo łatwa w Javie, oto wariant, który wyszukuje ziarno za pomocą wszystkich dostępnych rdzeni: 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();
    }
  }
}

Aby java noob, tak jak ja, musisz sufiksować numer wyjścia Li zmienić typ argumentu na long, tzn. randomString(long i)Aby się pobawić. :)
Fruit

21

Losowo zawsze zwraca tę samą sekwencję. Służy do tasowania tablic i innych operacji jako permutacji.

Aby uzyskać różne sekwencje, konieczne jest zainicjowanie sekwencji w pewnej pozycji, zwanej „seed”.

Funkcja randomSting otrzymuje liczbę losową w pozycji i (seed = -229985452) „losowej” sekwencji. Następnie używa kodu ASCII dla kolejnych 27 znaków w sekwencji po pozycji początkowej, aż wartość ta będzie równa 0. Zwróci to „hello”. Ta sama operacja jest wykonywana dla „świata”.

Myślę, że kod nie działał dla innych słów. Facet, który zaprogramował, który bardzo dobrze zna losową sekwencję.

To bardzo świetny kod maniaka!


10
Wątpię, czy „bardzo dobrze zna losową sekwencję”. Bardziej prawdopodobne, że wypróbował miliardy możliwych nasion, aż znalazł takie, które zadziałało.
dan04

24
@ dan04 Prawdziwi programiści nie tylko używają PRNG, pamiętają cały okres na pamięć i wyliczają wartości w razie potrzeby.
Thomas

1
„Losowo zawsze zwraca tę samą sekwencję” - wstaw () po Losowo lub pokaż jako kod. W przeciwnym razie zdanie jest fałszywe.
Gangnus,

14

Głównym jest, że klasa losowa zbudowana z tego samego materiału siewnego będzie generować ten sam wzór liczb za każdym razem.


12

Ta metoda, wywodząca się z odpowiedzi Denisa Tulskiego , generuje ziarno.

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

Z dokumentów Java jest to celowa funkcja przy określaniu wartości początkowej dla klasy Random.

Jeśli dwa wystąpienia Losowe zostaną utworzone z tym samym ziarnem i dla każdego zostanie utworzona ta sama sekwencja wywołań metod, wygenerują one i zwrócą identyczne ciągi liczb. W celu zagwarantowania tej właściwości określone algorytmy są określone dla klasy Losowo. Implementacje Java muszą używać wszystkich przedstawionych tutaj algorytmów dla klasy Random ze względu na absolutną przenośność kodu Java.

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

Dziwne, wydaje się, że istnieją domniemane problemy bezpieczeństwa związane z przewidywalnymi „losowymi” liczbami.


3
Dlatego domyślny konstruktor Random„ustawia ziarno generatora liczb losowych na wartość, która prawdopodobnie różni się od innych wywołań tego konstruktora” ( javadoc ). W bieżącej implementacji jest to połączenie bieżącego czasu i licznika.
martin

W rzeczy samej. Przypuszczalnie istnieją praktyczne przypadki zastosowania początkowej wartości nasion. Sądzę, że taka jest zasada działania tych pseudolosowych pilotów, które można zdobyć (RSA?)
deed02392

4
@ deed02392 Oczywiście istnieją praktyczne przypadki użycia do określania wartości początkowej. Jeśli symulujesz dane, aby zastosować jakieś podejście Monte Carlo do rozwiązania problemu, dobrze jest móc odtworzyć swoje wyniki. Ustawienie początkowego ziarna jest najłatwiejszym sposobem na to.
Dason,


3

Oto niewielka poprawa odpowiedzi Denisa Tulskiego . Skraca czas o połowę

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

Chodzi o ziarno wejściowe . Te same nasiona dają te same wyniki przez cały czas. Nawet jeśli ponownie uruchomisz program, to samo wyjście.

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());

}

Wynik

-755142161
-1073255141
-369383326
1592674620
-1524828502
------------
-755142161
-1073255141
-369383326
1592674620
-1524828502
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.