Niyə bu kod "salam dünyası" nı çap etmək üçün təsadüfi işarələrdən istifadə edir?

Aşağıdakı mətbu bəyanat "salam dünyası" nı çap etdirəcəkdir. Bunu hər kəs izah edə bilərmi?

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

randomString() görünür:

 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 mart ayının 03-də saat 07.33- də təyin olunub
@ 14 cavab

-229985452 bir nümunəsi müəyyən bir toxum parametri ilə yaradıldığında (bu halda, -229985452 və ya -147909649 ), bu başlanğıc dəyərdən başlayaraq təsadüfi ədədlərin yaranması üçün alqoritmi izləyir.

Eyni toxumla qurulan hər Random , hər dəfə ədədlərin eyni nişanını yaradır.

858
03 марта '13 в 7:40 2013-03-03 07:40 cavab Vulcan 03.03.2013 07:40 saat 03: 30-da verilir

Digər cavablar nəyə görə açıqlanır, amma burada necə.

Random nümunə üçün:

 Random r = new Random(-229985452) 

r.nextInt(27) yaradan ilk 6 ədəd:

 8 5 12 12 15 0 
border=0

r.nextInt(27) verilən Random r = new Random(-147909649) əmələ r.nextInt(27) ilk 6 ədəd aşağıdakılardır:

 23 15 18 12 4 0 

Sonra sadəcə bu rəqəmləri ` xarakterin tam təmsilinə (96) əlavə edin:

 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 Cavab Müqəddəs Müqəddəs Kitabda 03 Mart 'da 07:55' də verilir. 2013-03-03 07:55

Mən buradan tərk edəcəyəm. Bəziləri (CPU) qurtarmaq üçün çox vaxt var, sınaqdan azad olmağı bacarın :) Həmçinin, əgər bu formanı bir neçə fork-join-fu işlətmişsənsə, bu prosesin bütün prosessor nüvələrini yaza bilərik (yalnız mövzuları darıxdırıcı, sağ?) kodunuzu paylaşın. Mən çox minnətdar olardım.

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

Nəticə:

 -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 Cavab Denis Tulskiyə 03.03.2013 18:03 tarixində verilir

Burada hər kəs kodun necə işlədiyini və necə öz nümunələrini necə yarada biləcəyini izah edən bir çox iş görmüşdür, ancaq nəticədə axtarışın nəhayət ki, həll olunacağının əsas səbəbindən gözlənilən məlumatları izah edən bir nəzəri cavabı var kobud güc.

26 fərqli kiçik hərf Əlifba Σ . Müxtəlif uzunluqdakı sözlərin yaranmasına imkan vermək üçün, daha uzun alfabe Σ' := Σ ∪ {⊥} almaq üçün başqa bir terminator sembolünü əlavə edin.

α bir simvol və X-nin Σ' bərabər paylanmış təsadüfi dəyişən Σ' . Bu simvolu P(X = α) və onun informasiya məzmununu I(α) əldə etmək ehtimalı aşağıdakı kimi verilir:

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

I (α) = -Loqzon [P (X = α)] = -Loqzon (1/27) = LogSi (27)

Söz üçün ω ∈ Σ* və onun ⊥- tam analoq ω' := ω · ⊥ ∈ (Σ')*

I (ω): = i (ω ') = | ω '| * logo2 (27) = (| ω | + 1) * log2 (27)

Pseudo-təsadüfi saylı generator (PRNG) 32-bit toxumla başlayandan bəri, biz sözlərin çoxuna

λ = cinsiyyət [32 / log² (27)] - 1 = 5

ən azı bir toxum yaratmaq. 6 xarakterli bir söz axtarmaq olsa belə, hal-hazırda vəziyyətlərin təxminən 41,06% -nə nail olacağıq. Çox qorxmuram.

7 məktub üçün biz 1.52% -ə yaxınlaşdıq, ancaq mən çalışmıram:

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

Çıxışa baxın: http://ideone.com/JRGb3l

250
04 марта '13 в 12:49 2013-03-04 12:49 cavab xDD 04 mart '13 saat 12:49 'də verilir 2013-03-04 12:49

Bu toxumları axtarmaq üçün qısa bir proqram yazdım:

 import java.> 

O, mənim üçün arka planda çalışır, amma klassik bir pangram üçün kifayət qədər sözlər tapmışdır:

 import java.> 

( İdeon haqqında demo. )

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

65
03 марта '13 в 21:33 2013-03-03 21:33 Cavab İlmari Karonen tərəfindən 03.03.2013 21:33 2013-03-03 21:33 tərəfindən verilir

Mən bununla maraqlandım, bu təsadüfi söz generatorunu lüğət sözləri siyahısında işə saldım. Range: Integer.MX_VALUE üçün Integer.MIN_VALUE

15131 xit var.

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

Yazdırın

 the quick browny fox jumps over a lazy dog 
31
14 апр. Cavab Puru tərəfindən verilir - Apr 14 2014-04-14 01:47 '14 da 1:47 2014-04-14 01:47

Ən təsadüfi ədəd generatorları əslində "pseudo-təsadüfi" dir. Bunlar xətti əlaqəli generatorlar və ya LCG ( http://en.wikipedia.org/wiki/Linear_congruential_generator )

LCG sabit toxum ilə proqnozlaşdırılır. Əsasən, ilk məktubu verən toxumu istifadə edin və sonra hədəf xəttinə növbəti məktub vurun və LCG nömrəsinə neçə dəfə müraciət etdiyinizə qədər növbəti int (char) yaratmaqda davam edən bir proqram yazın, hər bir məktub yaratmaq.

26
04 марта '13 в 13:59 2013-03-04 13:59 Cavab Sinclair Schuller tərəfindən 04 Mart '13 'də 13:59' də verilir. 2013-03-04 13:59

Təsadüfi olanlar həmişə eyni ardıcıllığı qaytarırlar. Bu dəyişikliklər kimi diziləri və digər əməliyyatları qarışdırmaq üçün istifadə edilmişdir.

Fərqli ardıcıllıq əldə etmək üçün, "toxum" adlanan bir mövqedə ardıcıllığı başlamaq lazımdır.

Təsadüfi dəyər "təsadüfi" sətrin i (toxum = -229985452) mövqeyində təsadüfi bir sıra olur. Daha sonra ASCII kodu, toxum mövqeyindən sonra, bu dəyər 0-dəkə qədər ardıcıllıqdakı növbəti 27 simvol üçün istifadə olunur. Bu salam verir. Eyni əməliyyat "sülh" üçün həyata keçirilir.

Hesab edirəm ki, kod başqa bir sözlə işləməyib. Təsadüfi ardıcıllığı çox yaxşı bilən proqramçı olan adam.

Bu, çox gözəl bir koddur!

22
03 марта '13 в 7:54 2013-03-03 07:54 Cavab Arnaldo Ignacio Gaspar Véjar tərəfindən verilir 03.03.2013 07:54

Java ilə multi-threading çox sadədir, burada bütün mövcud çekirdekləri istifadə edərək bir toxum axtarır bir seçim var: 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 окт. Cavab İki The 05 oktyabr tərəfindən verilir . 2013-10-05 02:13 '13 at 2:13 2013-10-05 02:13

Hərəkət prinsipi eyni toxumla qurulan təsadüfi bir sinifdir, hər dəfə eyni ədəd nümunəsi yaradır.

13
13 июня '13 в 23:36 2013-06-13 23:36 Cavab verilir tomj0101 13 İyun, '13 'da 11:36 2013-06-13 23:36

Denis Tulsky'den əldə edilən bu üsul toxum meydana gətirir.

 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 Cavab sulai 07 mart '13 saat 16:26 'da verilir 2013-03-07 16:26

Java sənədlərində, bu təsadüfi Random üçün başlanğıc dəyərini təyin edərkən qəsdən bir funksiyadır.

Random iki nümunə eyni toxum ilə yaradılmışdır və onların hər biri üçün metod zəngləri eyni ardıcıllıqla həyata keçirilir, onlar eyni ədəd sequences yaradır və qaytarır. Bu əmlakı təmin etmək üçün Random sinif üçün müəyyən alqoritmlər müəyyən edilir. Java tətbiqləri Java kodunun mütləq taşınabilirliyi üçün təsadüfi sinifdə göstərilən bütün alqoritmləri istifadə etməlidir.

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

Ancaq, gözlənilən "təsadüfi" ədədlərin mövcudluğunda örtülü təhlükəsizlik problemləri olduğunu düşünürdünüz.

11
06 марта '13 в 13:01 2013-03-06 13:01 Cavab 06 mart 2013 - il tarixdə saat 13: 01-də verilmişdir

Bu "toxum" haqqında. Eyni toxum eyni nəticə verir.

8
31 июля '13 в 4:07 2013-07-31 04:07 Cavab Burak Keceli tərəfindən 31 İyul 2013 tarixində 4:07 ' də verildi 2013-07-31 04:07

Denis Tulskiyin cavabı üçün bir az inkişafdır. O, yarısını yarıya endirir.

 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 нояб. Cavab Ilya Gazman 03 Nov. 2016-11-03 18:58 '16 saat 18:58 'də 2016-11-03 18:58

tags ilə bağlı digər suallar bir sual və ya bir sual