PHP: En iyi rasgele sayılar

13 Cevap php

PHP'nin rand () fonksiyonu iyi rasgele sayılar vermez duydum. Bu yüzden daha iyi sonuçlar vermek için söylenir mt_rand () kullanmaya başladı. Ama bu sonuçlar ne kadar iyi mi? Onları tekrar geliştirmek için herhangi bir yöntem var mı?

Benim fikrim:

<?php
function rand_best($min, $max) {
    $generated = array();
    for ($i = 0; $i < 100; $i++) {
        $generated[] = mt_rand($min, $max);
    }
    shuffle($generated);
    $position = mt_rand(0, 99);
    return $generated[$position];
}
?>

Bu size "mükemmel" rasgele sayılar, bu olmamalıdır vermelidir?

Bana yardımcı olur umarım. Şimdiden teşekkürler!

13 Cevap

Pseudorandom number generators (PRNG) çok karmaşık bir canavar vardır.

Hiçbir gerçek "mükemmel" rasgele sayı jeneratörler var - aslında matematiksel fonksiyonlardan yapılabilir ki en yalancı rasgele vardır - onlar en çok niyet ve amaçlar için yeterince rastgele görünüyor.

Aslında, bir PRNG tarafından döndürülen bir dizi herhangi bir ek eylemler gerçekleştirerek gerçekten rastgeleliğine artmaz, ve aslında, sayı daha az rastgele olabilir.

Yani, benim en iyi tavsiyem, değerler etrafında karışıklık bir PRNG döndü yok. Amaçlanan kullanım için yeterince iyi bir PRNG kullanın, ve eğer değilse gerekirse, o zaman daha iyi sonuçlar üretebilen bir PRNG bulabilirsiniz.

Ve açıkçası, onu olduğu gibi oldukça iyi bir PRNG, bu yüzden muhtemelen en rahat kullanım için yeterince iyi olacak ki, mt_rand function uses the Mersenne twister görünür.

Edit

Rastgele bir dizi işlemleri gerçekleştirirken daha az rastgele yapabilirsiniz neden yorumlarda bir soru vardı. Örneğin, bazı PRNGs bit farklı bölgelerinde daha tutarlı, daha az rastgele sayılar dönebilirsiniz - high-end düşük sonunda daha rastgele olabilir.

Bu nedenle, yüksek düzey atılır, ve alt uç döndürülür işlemlerinde bu değer, PRNG döndürülen ilk değerden daha düşük rasgele olabilir.

Ben şu anda iyi bir açıklama bulamıyorum, ama ben merkezli olduğu için Java belgelerine Random.nextInt(int) method, which is designed to create a fairly random value in a specified range. That method takes into account the difference in randomness of the parts of the value, so it can return a better random number compared to more naive implementations such as rand() % range.

Ben ne yaptım Rasgeleliği "artırır" emin değilim. Ben 100 rasgele sayı üretmek ve anlamak ne daha sonra rastgele bir tanesini seçin.

Orada jeneratör işlevi temel bir önyargı (mt_rand ()), sonra yine çıktı bir şekilde yansıyacak sanki benim olasılık ders Hatırladığım kadarıyla, bu muhtemelen, Rasgeleliği artmaz.

Ne şekilde mt_rand) "kötü" (nedir?

Örneğin, belli bir sayıda yana edin. Sağlar ki mt_rand (1, 10) aralığında düşük sayılar tercih eder, yani "1" ve "2", ortalama% 10'dan daha fazla her biri ortaya çıkar. Sonra "iyileştirme" hala aynı sorunu muzdarip olacaktır.

Bir hatalı sırası dışında rastgele bir numarayı seçerek hala hatalı olacaktır.

<?php
  function random_number(){
      return 4; // return generated number
                // guaranteed to be random
  }
  ?>

Hepsi bir yana şaka, siz "rastgele" ya da ne "en iyi" olduğunu ne bir felsefi soru biniyorlar. İdeal Eğer rastgele numaraları prosedürü boyunca onlara birkaç desen olmasını isterdim. Genellikle sistem zaman tohum olarak kullanılır, ama aynı zamanda tohum, önce tohum olarak önceki rastgele numberth olarak önceki rastgele sayı kullandım. Sorun yeterince güçlü bir bilgisayar ve tam bilgi donanım çalışan ve jeneratör fonksiyonu ile, sen üretilen sayılar kümesinin tamamını tahmin etmek mümkün olacaktır. Eğer o oldu ya da olacak her olay tahmin etmek mümkün olacaktır evrenin tüm olası değişkenleri ve işlevleri biliyordu yeterince güçlü bir bilgisayar (bazı insanlar bu kategoriye koymak Tanrı) vardı Böylece eğer. Çoğu rasgele sayı üreteçleri kendi üzerinde ince ama desenleri görebilirsiniz tanıdığınız varsa, daha büyük olasılıkla onlar Beautiful Mind adam gibi ve bunları bir kliniğe teslim almak gerekir.

By popular demand: D

Ben periyodik random.org 1000 numaralarını alır cronjob (diyelim ki, bir kez bir saat) yazdı ve bir PHP diziye eklenir. Ben komut rasgele sayılar istediğinizde, bunu bir numarayı aramak için mt_rand (0,1000) kullanın. Birkaç ekstra yükü mikrosaniye, ama doğal atmosferik gürültü dayalı gerçek rasgele sayılar olsun.

kullanmak / dev / ramdom (linux aygıt gerçek rasgele sayı üreteci) mt_rand tohum

<?
$rnd_dev=mcrypt_create_iv(4, MCRYPT_DEV_RANDOM); //need "apt-get install php5-mcrypt"
$seed=ord(substr($rnd_dev, 0, 1))<<24 |
      ord(substr($rnd_dev, 1, 1))<<16 |
      ord(substr($rnd_dev, 2, 1))<<8 |
      ord(substr($rnd_dev, 3, 1));
mt_srand($seed);
echo mt_rand();
?>

Bu gerçek rasgele sayılar üretmek mümkün değildir, sizin için umut olabilir en iyi rand () işlev rastgele sonra rand () hiçbir yakın sağlar ne olduğu sözde rastgele. Bu http://en.wikipedia.org/wiki/Random_number_generator bir göz atın

PHP en rand() yerleşik beğenmezseniz, muhtemelen onların {inşa edilecek gibi görünüyor bu yana, ya onların yerleşik shuffle() kullanmak [(0)] olmamalıdır }.

Ben "endüstri standardı" shuffle şimdi Fisher-Yates shuffle yarım eminim.

Ben mt_rand dağılımı () endişe tahmin ediyorum. Ben test ettim ve çok düzeyli olduğunu ve hem sınırları dahildir.

Ben php kılavuzda mt_rand için belgeleri () yorumlarına benim test ekledik, ama nedeniyle çok uzun buraya girmek soluklu siyaset aptalca bir moderatör tarafından çıkarıldı.

"Mükemmel" bir rasgele sayı diye bir şey yoktur. Olursa olsun "mükemmel" subjektif ne anlamı var. Sadece sözde-rasgele elde edebilirsiniz.

Ben sadece doğru yönde bir işaret çalışıyordum. Sen mükemmel tırnak içinde olsa bile, mükemmel rastgele sayılar hakkında bir soru sordu. Ve evet, rastgelelik artırabilirsiniz. Hatta sezgisel ya da "doğal" algoritmaları, "atmosferik gürültü" gibi bu tür fikirleri uygulamak olabilir - ama yine de, herhangi bir şekilde, mükemmel değil değilsin.

Tru Rastgele sayılar

<?php
for ($i = -1; $i <= 4; $i++) {
    $bytes = openssl_random_pseudo_bytes($i, $cstrong);
    $hex   = bin2hex($bytes);

    echo "Lengths: Bytes: $i and Hex: " . strlen($hex) . PHP_EOL;
    var_dump($hex);
    var_dump($cstrong);
    echo PHP_EOL;
}
?>

ve aynı zamanda güvenli ;) Kripto

Cevap yıl önce kabul edilmiş olmasına rağmen, ben yeniden yeniden edeceğiz.

Bütün bu rastgelelik sistemin zaman bağlıdır beri, çok sistem saati ile MESS edelim! Bir operasyon bilgisayarda geçen süre miktarı aslında (diğer şeyler bu sunucuda oluyor özellikle) oldukça değişkendir, bu yüzden Microtime'da ile bu yararlanmak eğer ... (herhangi bir taşınabilir nanoTime komutları bulamadık)

$a='';
for (int $i=0; $i<9001; $i++)
{
    usleep(mt_rand(1000,10000));//Also eliminates timing attacks... possibly?
    $a=hash('SHA512',$a.uniqid(mt_rand().microtime(),true));
}
echo $a;

Sözde başka 23 bitleri her tekrarında ekliyoruz çünkü bu, entropi 207023 bit var, ama karşılıklı dayanışmanın bir şey var, bu yüzden daha az muhtemelen büyüklükte bir kaç emirlerdir. Hala oldukça iyi.

Eğer zaman gerçekten rastgele bir miktar almak PHP üzerinde herhangi bir operasyon biliyor musunuz? Gibi ... (RANDOM.org dışında) bazı web sitesi HTTP-talep ve onu alır zaman ölçme?

Random.org kullanarak, bu kullanabilirsiniz:

function getToken($length, $min, $max){
    $r = explode('
',file_get_contents('http://www.random.org/integers/num='.$length.'&min='.$min.'&max='.$max.'&col=1&base=10&format=plain'));

    $string = '';
    foreach ( $r as $char ) $string.=$char;
    return $string;
}

Bu gerçek rasgele numaralar vermelidir