Kodėl šis kodas naudoja atsitiktines eilutes, kad išspausdintų „sveikas pasaulis“?

Toliau pateikiamas spausdinimo pranešimas spausdins „hello world“. Ar kas nors tai paaiškins?

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

Ir randomString() atrodo taip:

 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(); } 
1619
03 марта '13 в 7:38 2013-03-03 07:38 0x56794E yra nustatytas kovo 03 '13, 07:38 2013-03-03 07:38
@ 14 atsakymų

Kai java.util.Random egzempliorius sukuriamas naudojant konkretų sėklų parametrą (šiuo atveju -229985452 arba -147909649 ), jis seka atsitiktinių skaičių generavimo algoritmą, pradedant nuo šios pradinės vertės.

Kiekvienas Random , kuriamas su ta pačia sėkla, kiekvieną kartą generuoja tą patį skaičių modelį.

858
03 марта '13 в 7:40 2013-03-03 07:40 atsakymas pateikiamas Vulcan kovo 3 d. 13 val. 7:40 2013-03-03 07:40

Kiti atsakymai paaiškina, kodėl, bet čia.

Random pavyzdžio atveju:

 Random r = new Random(-229985452) 

Pirmieji 6 numeriai, kuriuos r.nextInt(27) generuoja:

 8 5 12 12 15 0 

ir pirmieji 6 skaičiai, kuriuos r.nextInt(27) generuoja nurodytu Random r = new Random(-147909649) yra tokie:

 23 15 18 12 4 0 

Tada tiesiog pridėkite šiuos skaičius į ` simbolio“ (kuris yra 96) sveikąjį skaičių.

 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 
1094
03 марта '13 в 7:55 2013-03-03 07:55 atsakymas duotas Eng.Fouad kovo 03 '13, 7:55 2013-03-03 07:55

Aš tiesiog paliksiu čia. Kažkas, turintis daug (CPU) laiko atsikratyti, nedvejodami eksperimentuokite :) Be to, jei jūs įsisavinote kai kuriuos šakės prisijungimo-fu, kad šis dalykas būtų parašytas visiems procesoriaus šerdims (tik siūlai yra nuobodu, tiesa?), Prašome bendrinkite savo kodą. Būčiau labai dėkingas.

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

Išvada:

 -9223372036808280701 Using base: 'Z' stack -9223372036853943469 Using base: 'b' over -9223372036852834412 Using base: 'e' flow -9223372036838149518 Using base: 'd' rulez Took 7087 ms 
264
03 марта '13 в 18:03 2013-03-03 18:03 atsakymas duotas Deniui Tulskiui kovo 03 d. 13 val. 2013-03-03 18:03

Kiekvienas čia padarė daug darbo, paaiškindamas kodo veikimą ir parodydamas, kaip galite sukurti savo pavyzdžius, tačiau yra teorinis atsakymas į informaciją, paaiškinančią, kodėl galime pagrįstai tikėtis, kad bus rastas sprendimas, kuriuo galiausiai bus ieškoma brutalia jėga.

26 skirtingos mažosios raidės sudaro mūsų abėcėlę Σ . Jei norite sukurti skirtingo ilgio žodžius, pridėkite kitą terminatoriaus simbolį kad gautumėte išplėstą abėcėlę Σ' := Σ ∪ {⊥} .

Leiskite α būti simboliu ir X vienodai paskirstytu atsitiktiniu kintamuoju per Σ' . Tikimybė gauti šį simbolį P(X = α) ir jo informacinis turinys I(α) pateikiamas taip:

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

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

Žodžiui ω ∈ Σ* ir jo ⊥- pilnam analoginiam ω' := ω · ⊥ ∈ (Σ')*

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

Kadangi pseudo-atsitiktinių skaičių generatorius (PRNG) inicijuojamas 32 bitų sėklomis, galime tikėtis, kad dauguma žodžių iki

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

sukurti bent vieną sėklą. Net jei ieškosime šešių ženklų žodžio, mes vis dar pavyks apie 41,06% atvejų. Ne per daug nuskustas.

7 laiškams mes žiūrime arčiau kaip 1,52%, bet nesupratau, kad prieš bandant:

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

Žr. Išvestį: http://ideone.com/JRGb3l

250
04 марта '13 в 12:49 2013-03-04 12:49 atsakymas pateikiamas xDD kovo 04 d. 13 val. 12:49 2013-03-04 12:49

Aš parašiau trumpą programą, skirtą ieškoti šių sėklų:

 import java.> 

Jis dabar dirba fone, bet jis jau rado pakankamai žodžių klasikinei pomėgiai:

 import java.> 

(„ Demo on ideon“ ).

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

65
03 марта '13 в 21:33 2013-03-03 21:33 atsakymą pateikė Ilmari Karonen kovo 3 d. 13 d. 21:33 2013-03-03 21:33

Man tai buvo įdomu, todėl šį atsitiktinio žodžio generatorių paleidžiau žodyno žodžių sąraše. Diapazonas: Integer.MIN_VALUE už Integer.MAX_VALUE

Gavau 15131 peržiūrą.

 int[] arrInt = {-2146926310, -1885533740, -274140519, -2145247212, -1845077092, -2143584283, -2147483454, -2138225126, -2147375969}; for(int seed : arrInt){ System.out.print(randomString(seed) + " "); } 

Spausdinti

 the quick browny fox jumps over a lazy dog 
31
14 апр. atsakymas, kurį pateikė Puru - balandžio 14 d 2014-04-14 01:47 '14 at 1:47 2014-04-14 01:47

Dauguma atsitiktinių skaičių generatorių iš tikrųjų yra „pseudo-random“. Tai yra linijiniai kongruenciniai generatoriai arba LCG ( http://en.wikipedia.org/wiki/Linear_congruential_generator )

LCG yra nuspėjami su fiksuotomis sėkla. Iš esmės naudokite sėklą, kuri suteikia jums pirmąją raidę, ir tada parašykite programą, kuri toliau generuoja kitą int (char), kol paspaudžiate kitą raidę tikslinėje eilutėje ir užrašykite, kiek kartų jums reikėjo paskambinti LCG, Tęsti, kol generuoti kiekvieną raidę.

26
04 марта '13 в 13:59 2013-03-04 13:59 atsakymą pateikė Sinclair Schuller kovo 14 d. 13:59 2013-03-04 13:59

Atsitiktiniai visada grąžinami ta pačia tvarka. Jis buvo naudojamas masyvams ir kitoms operacijoms maišyti kaip permutacijas.

Kad gautumėte skirtingas sekas, reikia inicijuoti seką tam tikroje padėtyje, vadinamoje „sėkla“.

Atsitiktinė reikšmė gauna atsitiktinį skaičių "atsitiktinės" sekos i padėtyje (sėkla = -229985452). Tada ASCII kodas bus naudojamas sekančioms 27 simboliams sekoje po sėklų padėties, kol ši vertė yra 0. Tai grąžina jus. Ta pati operacija atliekama „taikai“.

Manau, kad šis kodas neveikė jokiais kitais žodžiais. Vaikinas, kuris užprogramavo, kad gerai žino atsitiktinę seką.

Tai labai kietas kodas!

22
03 марта '13 в 7:54 2013-03-03 07:54 atsakymą pateikė Arnaldo Ignacio Gaspar Véjar kovo 03 '13, 7:54 2013-03-03 07:54

Kadangi kelių sriegių įvedimas su „Java“ yra labai paprastas, čia yra parinktis, kuri ieško sėklų, naudodama visus turimus branduolius: 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(); } } } 
22
05 окт. Atsakymą pateikė „ TwoThe 05 oct. 2013-10-05 02:13 '13, 2:13, 2013-10-05 02:13

Veikimo principas yra atsitiktinė klasė, pastatyta su ta pačia sėkla, kiekvieną kartą kuriant tą patį skaičių modelį.

13
13 июня '13 в 23:36 2013-06-13 23:36 atsakymas pateikiamas nuo birželio 10 d., 13 d., 13 val. 11:36 2013-06-13 23:36

Šis metodas sukurtas iš Denis Tulsky .

 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 :/"); } 
13
07 марта '13 в 16:26 2013-03-07 16:26 atsakymas pateikiamas sulai kovo 13 d. 13, 16:26 2013-03-07 16:26

„Java“ dokumentuose tai yra sąmoninga funkcija, kai nustatoma pradinė „Random“ klasės vertė.

Jei su tuo pačiu sėklu sukuriami du atsitiktinės atrankos atvejai, ir kiekvienai iš jų vykdoma ta pati metodų skambučių seka, jie generuos ir grąžins identiškas skaičių sekas. Siekiant užtikrinti šią savybę, atsitiktinei klasei yra nustatyti tam tikri algoritmai. „Java“ diegimuose turėtų būti naudojami visi čia parodyti algoritmai atsitiktinei „Java“ kodo perkeliamumui.

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

Tačiau jūs manote, kad egzistuoja netiesioginės saugumo problemos, kai yra numatomi „atsitiktiniai“ numeriai.

11
06 марта '13 в 13:01 2013-03-06 13:01 atsakymas pateikiamas deed02392 kovo 13 d. 13:01 2013-03-06 13:01

Tai yra apie „sėklą“. Tos pačios sėklos duoda tą patį rezultatą.

8
31 июля '13 в 4:07 2013-07-31 04:07 atsakymą pateikė Burak Keceli , liepos 31 d. 13 d., 04:07 2013-07-31 04:07

Štai šiek tiek pagerėjo Denis Tulskiy atsakymas . Jis pertraukia laiką per pusę.

 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 :/"); } 
3
03 нояб. Atsakyti Ilya Gazman 03.11 . 2016-11-03 18:58 '16 at 18:58 2016-11-03 18:58

Kiti klausimai apie žymes arba Užduoti klausimą