Neden rastgele dizeler kullanan bu kod "merhaba dünya" yazdırıyor?


1769

Aşağıdaki basılı açıklama "merhaba dünya" yazdıracaktır. Herkes bunu açıklayabilir mi?

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

Ve randomString()şöyle görünüyor:

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
Bu özel tohumlar mükemmel bir şekilde çalışıyor. Rastgele gerçekten rastgele değildir, yalancıdır.
Kapı Tokmağı

341
Diğerlerinin söylediği gibi çalışıyor, çünkü rastgele değil. Bana göre daha ilginç bir soru, bunu yazan kişi, kaba kuvvet uygular mı yoksa belirli bir tohum için bir sonraki N değerleri için hangi rasgele üretileceğini tahmin etmenin kolay bir yolu olurdu. Kaba zorlama kolaydır ve modern donanım ile çok uzun sürmemelidir, bu yüzden bunu yapmak için uygun bir yoldu. Statik olduğu göz önüne alındığında, aramayı bir ağ üzerinden kolayca dağıtabilirsiniz.
jmoreno

78
Ben amacını merak niçinde for (int n = 0; ; n++). Kullanabilirler for(;;)ya da while(true)onun yerine!
Müh.Fouad

13
Gerçekten rastgele bir sırayla, olası her dize sonunda ortaya çıkacaktır. Yüksek kaliteli sözde rastgele dizide makul her olası uzunluk dizisini (log_s (N) - n) bit bekleyebilir (burada N, PRNG'lerin dahili durumundaki bit sayısıdır ve n küçük bir sayıdır, kolaylık için 8'i seçelim ) döngüsünde görünür. Bu kod, neredeyse tüm 8 biti geri alan serbestçe seçilmiş bir sabit kodlu başlangıç ​​noktasının (backtick karakterinin değeri) kullanımından biraz yardım alır.
dmckee --- eski moderatör kedi yavrusu

13
Bu, birkaç yıl önce yazdığım bir gönderiden. vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
Peter Lawrey

Yanıtlar:


917

java.util.RandomBelirli bir tohum parametresiyle (bu örnekte -229985452veya -147909649) bir örneği oluşturulduğunda , o tohum değeriyle başlayan rastgele sayı oluşturma algoritmasını izler .

Her RandomAynı tohum inşa numaraların aynı desene her zaman üretecektir.


8
@Vulcan - javadoc, tohumun 48 bit olduğunu söylüyor. docs.oracle.com/javase/7/docs/api/java/util/Random.html . Ve ayrıca, gerçek tohumlar 32 bit değerlerdir.
Stephen C

80
Taklidi sayı dizisinin her bir elemanı 27 modülo alınır ve her biri 6 eleman vardır "hello\0"ve "world\0". Eğer gerçekten rastgele bir jeneratör varsayalım, aradığınız dizinin elde edilmesinin 27 ^ 6 (387,420,489) cinsinden 1'i olurdu - bu yüzden oldukça etkileyici ama akıl almaz!
Russell Borogove

17
@RussellBorogove: Ancak bu oranlar ve 2 ^ 64 olası tohumla, bu diziyi veren 47.6 milyar tohum değeri bekleniyor. Sadece bir tane bulma meselesi.
dan04

8
@ dan04 - Bu tahminde bulunmaya pek istekli değildim; PRNG'nin uygulanmasına bağlı olarak, tohum kelimesinin boyutu durumun boyutuna eşit olmayabilir ve sıra yolları eşit olarak dağıtılamayabilir. Ama yine de, oranlar kesinlikle iyi ve bir çift bulamadıysanız, farklı kasa ( "Hello" "World") ile veya tekrar 122-kyerine kullanmayı deneyebilirsiniz 96+kveya ...
Russell Borogove

7
@ ThorbjørnRavnAndersen Javadoc , "Random sınıfı için belirli algoritmalar belirtildiğini belirtir. Java uygulamaları, Java kodunun mutlak taşınabilirliği uğruna, Random sınıfı için burada gösterilen tüm algoritmaları kullanmalıdır.
FThompson

1137

Diğer cevaplar nedenini açıklıyor, ama işte nasıl.

Bir örneği verildiğinde Random:

Random r = new Random(-229985452)

Üreten ilk 6 sayı r.nextInt(27):

8
5
12
12
15
0

ve ilk 6 numaraları r.nextInt(27)verilmiştir oluşturur Random r = new Random(-147909649)gibidir:

23
15
18
12
4
0

Sonra bu sayıları karakterin tamsayı gösterimine ekleyin `(96'dır):

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
Bilgiçlikle, new Random(-229985452).nextInt(27)daima 8 döndürür.
user253751

1
@immibis neden? Yani Random () her seferinde rastgele bir sayı döndürmeli, düzeltilmiş bir sıralı sayı kümesi değil mi?
roottraveller

5
@rootTraveller Başlangıç ​​olarak, new Random()bir sayı döndürmez.
user253751

2
Bu tohumların hesaplanmasının bir yolu var mı? Biraz mantık olmalı ... yoksa sadece kaba kuvvet mi?
Sohit Gore

2
@SohitGore Java'nın varsayılanının Randomkriptografik olarak güvenli olmadığı göz önüne alındığında (Mersenne Twister olduğundan eminim, ama bana bu konuda alıntı yapmayın), muhtemelen "Bu numaraları istiyorum" - " kullanacağım tohum ". Standart C lineer uyumlu jeneratörle benzer bir şey yaptım.
Monica'nın Davası

280

Sadece burada bırakacağım. Kimin (CPU) yedeklemesi için çok fazla zamanı varsa, denemekten çekinmeyin :) Ayrıca, bu şeyin tüm CPU çekirdeklerini yakmasını sağlamak için bazı fork-join-fu konusunda uzmanlaştıysanız (sadece iş parçacıkları sıkıcı, değil mi?) senin kodun. Çok makbule geçer.

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

Çıktı:

-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), aralık dahilinde anlamına gelir [0, 26].
Müh.Fouad

30
@Vulcan Çoğu tohum maksimum değere çok yakın, tıpkı 1 ile 1000 arasında rastgele sayılar seçerseniz, topladığınız çoğu sayının üç basamağı olacaktır. Bunu düşündüğünüzde şaşırtıcı değil :)
Thomas

18
@Vulcan Aslında matematik yaparsanız, sıfıra kadar maksimum değere yakın olduklarını göreceksiniz (tohumun üretim kodunda imzasız olarak yorumlandığını düşünüyorum). Ancak basamak sayısı gerçek değerle sadece logaritmik olarak büyüdüğünden, sayı gerçekten olmadığında gerçekten yakın görünüyor.
Thomas

10
Mükemmel cevap. Ve bonus puanlar için, son rastgele rastgele başlangıç ​​için gerekli 4 tohum dizisini üretecek bir Random başlatacak bir tohum bulabilir misiniz?
Marek

13
@Marek: Sahte rasgele tanrıların böyle bir davranışı onaylayacağını sanmıyorum.
Denis Tulskiy

254

Buradaki herkes, kodun nasıl çalıştığını açıklamak ve kendi örneklerinizi nasıl oluşturabileceğinizi göstermek için harika bir iş çıkardı, ancak işte kaba kuvvet aramasının nihayetinde bulacağını bir çözümün var olmasını neden makul bir şekilde beklediğimizi gösteren bir bilgi teorik cevabı.

26 farklı küçük harf alfabemizi oluşturur Σ. Farklı uzunluklarda kelimeler üretilmesine izin vermek için, genişletilmiş bir alfabe elde etmek için bir sonlandırıcı sembolü ekliyoruz Σ' := Σ ∪ {⊥}.

Izin αvermek bir sembol ve X eşit dağılmış rastgele değişken üzerinde Σ'. Bu simgeyi elde etme olasılığı P(X = α)ve bilgi içeriği I(α)aşağıdakiler tarafından verilir:

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

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

Bir kelime ω ∈ Σ*ve ⊥-sonlandırılan karşılığı için ω' := ω · ⊥ ∈ (Σ')*,

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

Pseudorandom Number Generator (PRNG) 32 bitlik bir tohumla başlatıldığından, çoğu uzun kelimeyi

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

en az bir tohum tarafından üretilir. 6 karakterlik bir kelime arayacak olsak bile, zamanın yaklaşık% 41.06'sında başarılı olurduk. O kadar da eski püskü değil.

7 harf için% 1.52'ye daha yakından bakıyoruz, ancak denemeden önce bunu fark etmemiştim:

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

Çıktıya bakın: http://ideone.com/JRGb3l


bilgi kuramım biraz zayıf ama bu kanıtı seviyorum. Birisi bana lambda hattını açıklayabilir mi, açıkça birisinin bilgi içeriğini diğeriyle paylaşıyoruz, ama bu neden bize kelime uzunluğunu veriyor? Dediğim gibi çok açık paslı özür dilemek için özür dilerim (NB shannon limit-kod çıkışından bir şeydir)
Mike HR

1
@ MikeH-R Lambda çizgisi I(⍵)yeniden düzenlenmiş denklemdir. I(⍵)32 (bit) ve |⍵|5 (sembol) olduğu ortaya çıkıyor.
iceman

67

Bu tohumları bulmak için hızlı bir program yazdım:

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

Şimdi arka planda çalışıyor, ama zaten klasik bir pangram için yeterli kelime bulundu:

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

( İdeone hakkında demo. )

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


35

Bu ilgimi çekti, bu rastgele kelime oluşturucuyu sözlük kelime listesinde çalıştırdım. Aralık: Tamsayı.MIN_VALUE - Tamsayı.MAX_VALUE

15131 sonuç aldım.

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

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

Baskılar

the quick browny fox jumps over a lazy dog 

7
Benim günümde adam yaptın: DI, Long.Min / Max ile denedim ve meslektaşlarımın isimlerini aradım ve sadece peter buldum: (peter 4611686018451441623 peter 24053719 peter -4611686018403334185 peter -9223372036830722089 peter -461168601840333198807408197 4611686017645756173 peter 781631731 peter 4611686019209019635 peter -9223372036073144077 peter -4611686017420317288 peter 1007070616 peter -9223372035847705192)
Marcel

25

Çoğu rasgele sayı üreteci aslında "sahte rasgele" dir. Bunlar Doğrusal Konjügasyon Jeneratörleri veya LCG'lerdir ( http://en.wikipedia.org/wiki/Linear_congruential_generator )

LCG'ler sabit bir tohum göz önüne alındığında oldukça öngörülebilirdir. Temel olarak, ilk mektubunuzu veren bir tohum kullanın, ardından hedef dizenizdeki bir sonraki mektubu vuruncaya kadar bir sonraki int (char) oluşturmaya devam eden bir uygulama yazın ve LCG'yi kaç kez çağırmanız gerektiğini yazın. Her harfi üretene kadar devam edin.


3
sahte olmayan rasgele sayı üreteci örneği
chiliNUT

1
@chiliNUT Bu tür jeneratörler harici aygıtlardır. Bazı elektronik lambalar. Ya da 0 veya 1 okunan kötü yazılmış bit. Rasgele sayıların saf dijital üretecini yapamazsınız, dijital algoritmalar rastgele DEĞİLDİR, kesinlikle kesindir.
Gangnus

@chiliNUT Birçok işletim sistemi entropi toplar . Örneğin Linux'ta /dev/urandomrastgele verileri okumak için cihazı kullanabilirsiniz . Ancak bu kıt bir kaynaktır. Dolayısıyla, bu tür rastgele veriler normalde PRNG'leri tohumlamak için kullanılır.
Adrian W

@AdrianW Wikipedia diyor urandomhala rastgele rasgele en.wikipedia.org/wiki//dev/random
chiliNUT

1
Evet, ancak kriptografik olarak güvenlidir, bu da yaratılmış rastgele dizilerle kaba kuvvet saldırıları ("rastgele" dizi "merhaba dünya" için tohum bulmak gibi) anlamına gelmez /dev/random. Yukarıda alıntıladığım makalede, Linux çekirdeği klavye zamanlamaları, fare hareketleri ve IDE zamanlamalarından entropi ürettiğini ve rastgele karakter verilerini / dev / random ve / dev / urandom özel dosyaları aracılığıyla diğer işletim sistemi süreçleri için kullanılabilir hale getirdiğini söylüyor . Bu gerçekten rastgele olduğuna inanmama izin verdi. Belki de tam olarak doğru olmayabilir. Ama /dev/randomen azından bir entropi içeriyor .
Adrian W

23

Java ile çoklu iş parçacığı kullanımı çok kolay olduğu için, mevcut tüm çekirdekleri kullanarak bir tohum arayan bir varyant 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();
    }
  }
}

Benim gibi java noob için, çıkış numarasını sonekine eklemeniz Lve argüman türünü değiştirmeniz gerekir long, yani randomString(long i)oyun oynamak için. :)
Meyve

21

Rastgele daima aynı sırayı döndürür. Dizileri karıştırmak ve permütasyon olarak diğer işlemleri yapmak için kullanılır.

Farklı sekanslar elde etmek için sekansı "tohum" adı verilen bir pozisyonda başlatmak gerekir.

RandomSting, rastgele sayıyı "rastgele" dizinin i konumunda (tohum = -229985452) alır. Daha sonra bu değer 0'a eşit olana kadar tohum pozisyonundan sonraki dizide sonraki 27 karakter için ASCII kodunu kullanır. Bu "merhaba" döndürür. Aynı işlem "dünya" için de yapılır.

Kodun başka kelimeler için işe yaramadığını düşünüyorum. Programlanan adam rastgele diziyi çok iyi biliyor.

Çok büyük bir geek kodu!


10
"Rastgele diziyi çok iyi biliyorsa" şüpheliyim. Büyük olasılıkla, çalışan bir tane bulana kadar milyarlarca olası tohum denedi.
dan04 04.03.2013

24
@ dan04 Gerçek programcılar sadece PRNG'yi kullanmazlar, tüm dönemi kalpten hatırlarlar ve değerleri gerektiği gibi numaralandırırlar.
Thomas

1
"Rastgele her zaman aynı sırayı döndürür" - Rastgele sonra put () veya kod olarak gösterir. Aksi takdirde cümle yanlıştır.
Gangnus

14

Temel, aynı tohumla inşa edilen Rastgele Sınıf olup, her seferinde aynı sayı desenini üretecektir.


12

Denis Tulskiy'nin cevabından türetilen bu yöntem tohumu üretir.

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 belgelerinden, bu Random sınıfı için bir tohum değeri belirtilirken kasıtlı bir özelliktir.

Aynı tohumla iki Rastgele örnek oluşturulursa ve her biri için aynı yöntem çağrıları dizisi yapılırsa, aynı sayı dizilerini oluşturur ve döndürürler. Bu özelliği garanti etmek için Random sınıfı için belirli algoritmalar belirtilir. Java uygulamaları, Java kodunun mutlak taşınabilirliği uğruna, Random sınıfı için burada gösterilen tüm algoritmaları kullanmalıdır.

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

Tuhaf, tahmin edilebilir 'rastgele' sayılara sahip olmanın örtük güvenlik sorunları olduğunu düşünürdünüz.


3
Varsayılan yapıcı nedeni budur Random( "Bu yapıcı diğer herhangi çağırma farklı olması çok muhtemel bir değere rasgele sayı üreteci çekirdeğini ayarlar" javadoc ). Mevcut uygulamada bu, şimdiki zaman ile bir sayacın birleşimidir.
martin

Aslında. Muhtemelen başlangıç ​​tohum değerini belirtmek için pratik kullanım örnekleri vardır.
Alabileceğiniz sözde anahtarlıkların

4
@ deed02392 Tabii ki bir tohum değeri belirtmek için pratik kullanım örnekleri vardır. Bir sorunu çözmek için bir çeşit monte carlo yaklaşımı kullanmak için verileri simüle ediyorsanız, sonuçlarınızı çoğaltmak iyi bir şeydir. Başlangıç ​​tohumunun ayarlanması bunu yapmanın en kolay yoludur.
Dason


3

İşte Denis Tulskiy'nin cevabı için küçük bir gelişme . Zamanı yarıya indirir

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

Her şey girdi tohumuyla ilgili . Aynı tohum her zaman aynı sonuçları verir. Programınızı tekrar tekrar çalıştırsanız bile bu aynı çıktıdır.

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

}

Çıktı

-755142161
-1073255141
-369383326
1592674620
-1524828502
------------
-755142161
-1073255141
-369383326
1592674620
-1524828502
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.