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();
}
n
wfor (int n = 0; ; n++)
. Mogą użyćfor(;;)
lubwhile(true)
zamiast!Odpowiedzi:
Gdy instancja
java.util.Random
jest konstruowana z określonym parametrem początkowym (w tym przypadku-229985452
lub-147909649
), postępuje zgodnie z algorytmem generowania liczb losowych rozpoczynającym się od tej wartości początkowej .Każde
Random
zbudowane z tego samego materiału siewnego będzie generować ten sam wzór liczb za każdym razem.źródło
"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!"Hello"
"World"
) lub używając122-k
zamiast96+k
, lub ...Inne odpowiedzi wyjaśniają dlaczego, ale oto jak.
Biorąc pod uwagę przykład
Random
:Pierwsze 6 liczb, które
r.nextInt(27)
generuje to:a pierwsze 6 liczb, które
r.nextInt(27)
generuje podaneRandom r = new Random(-147909649)
to:Następnie po prostu dodaj te liczby do reprezentacji liczb całkowitych znaku
`
(czyli 96):źródło
new Random(-229985452).nextInt(27)
zawsze zwraca 8.new Random()
nie zwraca wcale liczby.Random
nie 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.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.
Wynik:
źródło
nextInt(27)
oznacza w zasięgu[0, 26]
.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 symboluP(X = α)
oraz jego zawartości informacyjnejI(α)
są określone przez:Dla słowa
ω ∈ Σ*
i jego⊥-
zakończonego odpowiednikaω' := ω · ⊥ ∈ (Σ')*
mamyPonieważ 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
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:
Zobacz wynik: http://ideone.com/JRGb3l
źródło
I(⍵)
uporządkowanym równaniem.I(⍵)
ma 32 (bitów) i|⍵|
okazuje się być 5 (symbolami).Napisałem szybki program do znalezienia tych nasion:
Mam go teraz uruchomionego w tle, ale znalazłem już wystarczająco dużo słów na klasyczny pangram:
( Demo na ideone. )
Ps.
-727295876, -128911, -1611659, -235516779
.źródło
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ń.
Wydruki
źródło
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ę.
źródło
/dev/urandom
urządzenia do odczytu losowych danych. Jest to jednak rzadki zasób. Tak więc takie losowe dane są zwykle wykorzystywane do inicjowania PRNG.urandom
wciąż jest pseudolosowo pl.wikipedia.org/wiki//dev/random/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/random
przynajmniej zawiera trochę entropii.Ponieważ wielowątkowość jest bardzo łatwa w Javie, oto wariant, który wyszukuje ziarno za pomocą wszystkich dostępnych rdzeni: http://ideone.com/ROhmTA
źródło
L
i zmienić typ argumentu nalong
, tzn.randomString(long i)
Aby się pobawić. :)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!
źródło
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.
źródło
Ta metoda, wywodząca się z odpowiedzi Denisa Tulskiego , generuje ziarno.
źródło
Z dokumentów Java jest to celowa funkcja przy określaniu wartości początkowej dla klasy Random.
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.
źródło
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.Chodzi o „nasiona”. Te same nasiona dają ten sam rezultat.
źródło
Oto niewielka poprawa odpowiedzi Denisa Tulskiego . Skraca czas o połowę
źródło
Wynik
źródło