Sıfırdan bir rastgele sayı üretmek için nasıl

12 Cevap java

Nasıl bir rasgele sayı randomizasyon sürecinde yardımcı olacaktır dil / dış API herhangi bir yerleşik özellikleri kullanmadan sıfırdan, yani elde edilebilir?

Örneğin php a rand () fonksiyonu ve bir tohum işlevi vardır, ve ben java da benzer bazı şeyler vardır eminim.

Vb şimdiki zaman almak için yerleşik işlevleri kullanabilirsiniz, ancak bir rastgele sayı üretme süreci gerçek kodunuz tarafından yapılmalıdır.

Herhangi bir fikir?

12 Cevap

Bazı ilk tohum numarasını alır ve yeni sözde rasgele sayılar üretmek için büyük ve iyi aldı numarası ile çarpın. Aslında bu pek çok dil ne olduğunu.

int seed = 94664704;
public int rand() {
    seed = 23*seed % 10e8 + 1;
    return seed % 10e5;
}

Benim lise formül koleksiyonundan alınan, Formeln und Tafeln, sayfa 8.

Java aslında onlar için javadoc sonraki rasgele sayı seçmek nasıl ayrıntıları java.util.Random:

Bir sonraki genel sözleşme bir int değer döndürür ve argüman bit 1 ve 32 (dahil) arasında ise, o zaman döndürülen değeri birçok düşük sıralı bit her biri, (yaklaşık) bağımsız seçilen bit değerleri olmasıdır . 0 veya 1 olmak üzere (yaklaşık) eşit olasılıkla aşağıdaki gibi bir yöntem sonraki sınıfı Random tarafından uygulanmaktadır olduğunu:

 synchronized protected int next(int bits) {
	   seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
	   return (int)(seed >>> (48 - bits));
 }

Seminumerical Algoritmalar, bölüm 3.2.1: DH Lehmer tarafından tanımlanan ve Bilgisayar Programcılığı, Cilt 2 Sanatı Donald E. Knuth tarafından tarif edildiği gibi, doğrusal congruential pseudorandom numarası üreteci.

Zorunlu Dilbert and xkcd referanslar.

Cidden, sorunuzun cevabı no, there is no way to generate a truly random number from scratch - bazı dış entropi kullanmanız gerekir. Muhtemelen aklında bir pseudorandom numarası var. Bu durumda istediğiniz pseudorandomness tam derecesini belirtmek zorunda.

Özellikle, bazı gönderdi cevaplar test verileri oluşturmak gibi amaçlar için çok makul pseudorandom jeneratörler sağlayacaktır, ancak doğru şifreleme için uygun bir jeneratör uygulamak çok zordur.

İşte list of pseudorandom number generators Vikipedi bulunuyor.

Iyi seçilmiş parametreler için, basit ve oldukça yüksek kalitede - Bir linear congruential generator uygulamak.

Eğer kaliteli bir rastgele sayı gerekiyorsa, o zaman seçtiğiniz dilde Mersenne twister rasgele sayı üreteci uygulamaya bakmak gerekir. Orada net etrafında yüzen hazır uygulamaları bir yeri vardır, bu yüzden sadece kullanmak istediğiniz birini seçebilirsiniz.

Eğer kir şeyle başa çıkabilirim, sadece linear congruential generator kullanın.

çoğu dil java Math.random gibi bir PRNG function () var. PRNG genellikle şimdiki zaman ya da seçtiğiniz bir şey gibi bir değere ekilmiştir.

Daha güvenli bir şey için, şimdiki zaman daha entropi büyük bir kaynak gerekiyor. Java.security.SecureRandom gibi A sınıfı olduğunu uygular.

Bir kaliteli PRNG Mersenne Twister algoritma.

Çok daha basit PRNG en fazla temel uygulamalar için, C belgelerine bu gibi vardır:

int rand(void)
{
  next = next * 1103515245 + 12345;
  return (unsigned int)(next/(2 * (RAND_MAX +1L)) % (RAND_MAX+1L));
}

void srand(unsigned int seed)
{
  next = seed;
}

Bu test cihazı kullanarak PRNG kalitesini test edebilirsiniz: http://www.phy.duke.edu/~rgb/General/dieharder.php

Eğer gerçekten rastgele istiyorsanız, bir zar haddeleme robot inşa ve daha sonra buna göre programlamak gerekir. Ya bu adam yapılan bir satın:

DiceOMatic

Eğer cehennem bükük bu kendiniz yapıyor iseniz doğrusal congruential jeneratör Wikipedia'nın tartışma, terbiyeli ve erişilebilir:

http://en.wikipedia.org/wiki/Random%5Fnumber%5Fgeneration#Computational%5Fmethods

, Siz kendiniz yapmak isterdim neden ben hayal edemiyorum rağmen en iyi dil ve / veya işletim ortamları zaten sözde-rastgele test kaynakları sağlamak.

Sorunuzu biraz belirsiz. Eğer somut bir sorunu çözmeye çalışıyoruz? Sadece meraktan soruyorum soran var mı?

Ben doğru anlamak, çoğu dil / API'ler sunuyoruz yeniden uygulamak rasgele sayı üretimi istiyorum. Bunu yapmak için, bir sözde-rasgele jeneratör uygulamak gerekir. Bu nedenle okuma ve düşünme bir sürü yapmak için hazırlıklı olmak oldukça karmaşık bir matematiksel konu (Eğer doğru yapmak istiyorsanız), olduğunu. İyi bir başlangıç ​​noktası Pseudorandom number generators üzerine Wikipedia makale olurdu

Ben aslında bu merak oldum. I Math.random JavaScript uygulandığında aslında nasıl yapıldığını bakmak için zaman aldı. Ben bir tane yapmak için en iyi yol değildir eminim rağmen ben ancak, benim kendi küçük rastgele jeneratör yapmak yoktu ve ben bu performans söz konusu olduğunda çok verimli olmadığından kesinlikle eminim.

(function() {
 var rand = "0.";

 for(var i=10; i>=0; i--)
     {
       rand = rand + (function() {
         var start = new Date().getTime();

         for(var i=100000; i>=0; i--) { }
          return new Date().getTime() - start;
       })();
     }

  return eval(rand);
})();

Sadece ben kendime sorduğumda ile gelip düşündüm "Nasıl bir bilgisayar muhtemelen rastgele bir sayı ile gelebilir?" aslında oldukça basit. Çoğunuz muhtemelen sadece yukarıda koduna bakarak bilemez gibi, rasgele sayılar aslında bir for loop işlemek için bilgisayar için gereken süreyi tarafından oluşturulur. Tabii bilgisayar, işlem verileri çok hızlı bir şekilde (verilerin işlenmesi için yapılıyor). Bu nedenle, biz bunu en az bir milisaniye veya öylesine için bilgisayarı gecikme olacağı büyük bir döngü vermek zorunda kaldı. (Bu ben de verimsiz olduğunu söyledi varmaya ne olduğunu.) Döngünün infaz tamamlandıktan sonra, biz sadece döngü başlamış zaman ve sona erdi zaman arasındaki farkı toplandı. Bu, birkaç milisaniye ile sonuçlanır. Biz bu döngüler on kez çalıştırın ve 0. dizenin sonuna zaman ekleyerek bu döngüler tamamlamak için gereken ne kadar zaman log. Bilgisayar diğer zamanlarda hızla zamanlarda ve yavaş yavaş verileri işlemek için izin verir CPU rastgele ani çünkü bu, tamamen rasgele sayıda sonuçlanır. Fonksiyonunun sonunda, biz sadece bir ondalık dize dönüştürmek ve geri!

Sistem saatini kullanın. Sonra karma.

Ayrık matematiksel cihaz olma Bilgisayarlar dış müdahale olmaksızın saf rasgele sayı üreten aciz. Aşağıdaki kodu oldukça kullanışlı rastgele sayı üretir:

public static synchronized String getAutoGenId(){
    StringBuilder autogenID=new StringBuilder();
    try 
    {   

        Random rand = new Random();
        autogenID.append(Long.toString(System.nanoTime()));
        autogenID.append(Integer.toString(rand.nextInt(99)));
        if(autogenID.toString().length()<15)
        {
            autogenID.append(Integer.toString(rand.nextInt(9)));
        }

    } catch (Exception e) {
        //Do something
    } 
    return autogenID.toString();
}

Yoksa siz de ilginç UUID uygulanmasını çalışmaya bulabilirsiniz