PHP'de rasgele sayılar üretme hakkında birkaç kelime. PHP rastgele değerinde bir diziden rastgele bir değer nasıl seçilir

  • 03.11.2019

Nasıl yaptığımı birkaç kez sordum alıntıların rastgele çıktısı sitenizde blokta " Akıllı Alıntılar". Ayrıca, buradaki sorunun insanların yanlış anlaşılmasıyla ilgili olduğunu bulmayı başardım, php'de diziden rastgele eleman nasıl alınır. Görev basittir, ancak yine de sorular ortaya çıktığı için onlara cevap vermek gerekir.

Kodu hemen vereyim. Diyelim ki bir dizi tırnak içeren bir dizi var. Ve bunlardan rastgele birini seçip çıktı almanız gerekiyor:

$tırnak = dizi(); // Boş bir diziyi başlat
$quotes = "Düşüncelerinize dikkat edin, onlar eylemlerin başlangıcıdır."; // İlk alıntı
$quotes = "Hayatta kalanlar en zeki veya en güçlü değil, değişime en açık olandır."; // İkinci alıntı
$quotes = "Hayat bir dağdır: yavaş çık, hızla aşağı in."; // Üçüncü alıntı
$quotes = "İnsanlar zengin olmak istemez, insanlar diğerlerinden daha zengin olmak ister."; // Dördüncü alıntı
$sayı = mt_rand(0, say($tırnak) - 1); // 0'dan (dizi uzunluğu eksi 1) dahil olmak üzere rastgele bir sayı alın
echo $tırnak[$sayı]; // Çıktı teklifi
?>

kilit nokta rastgele sayı alma. Tek yapmanız gereken doğru sınırları belirlemek. Dizinin tüm uzunluğu boyunca rastgele bir öğe seçmeniz gerekiyorsa, bu 0 önceki ( dizi uzunluğu eksi 1). Ve sonra sadece verilen rasgele indeks ile diziden eleman çekin.

Tırnak içeren göreve gelince, bunları bir veritabanında saklamak daha iyidir. Prensip olarak, site çok basitse, bir metin dosyasında mümkündür. Ancak bir veritabanındaysa, kullanmak daha iyidir RAND() ve SINIR içinde SQL sorgusu böylece veritabanından hemen tek ve rastgele bir fiyat teklifi alırsınız.

  • İtibaren:
  • Kayıtlı: 2014.07.07
  • Gönderiler: 3,775
  • Sadece PunBB'yi seviyorum:
  • 5 yıllar 6 aylar,
  • Seviyor: 463

Konu: PHP'de bir diziden rastgele bir değer nasıl seçilir

Bu fonksiyon ile bir dizinin rastgele bir elemanını (veya elemanlarını) seçebiliriz. Evet, tam olarak element veya elementler! Bir eleman olabilir veya birkaç tane olabilir. Her şey karşı karşıya olduğunuz göreve bağlıdır.

Ancak burada, fonksiyonun elemanın değerini değil, anahtarını (veya birkaç eleman varsa anahtarlarını) döndüreceği unutulmamalıdır.

Parantez içinde parametre olarak, fonksiyon, birlikte çalıştığımız dizinin adını ve seçilecek eleman sayısını alır.

Genel olarak, her şey basit! Ve tüm bunlara örneklerle baktığımızda daha da kolaylaşacak.

Diziden rastgele tek bir eleman seçerek başlayalım.

2 tarafından yanıtla PunBB

  • İtibaren: Moskova, Sovkhoznay 3, apt. 98
  • Kayıtlı: 2014.07.07
  • Gönderiler: 3,775
  • Sadece PunBB'yi seviyorum:
  • 5 yıllar 6 aylar,
  • Seviyor: 463

Diyelim ki sitemizin en üstünde bir yerde bazı alıntılar göstermek istiyoruz. Tabii ki, teklifler değişmeli. Sitenizi her ziyaret ettiğinizde, kullanıcının yeni bir teklif görmesini istersiniz.

Muhtemelen tahmin ettiğiniz gibi, bunu uygulamanın en kolay yolu, mevcut tüm alıntıları bir diziye koymak ve ardından bu diziden rastgele bir öğe seçip ekranda görüntülemektir.

Dizide ne kadar çok tırnak varsa, tekrarlanma olasılıkları o kadar az olur.

Ama bir örnek vermek gerekirse, çok uğraşmayacağım ve dizime 7 atasözü koyacağım.

Ardından, array_rand () işlevinin sonucunu gireceğim bir değişken oluşturmam gerekecek. Parantez içinde, bu fonksiyonun iki argümanı olacaktır: dizimizin adı ve ihtiyacımız olan rastgele eleman sayısı.

Daha önce de söylediğim gibi, işlev, öğenin değerini değil, anahtarını (veya listedeki numarasını) döndürür. Böylece rastgele elemanın anahtarı değişkende saklanacaktır.

Bundan sonra, ekranda istenen elemanın değerini göstermem gerekiyor. Bunu yapmak için dizinin adını ve köşeli parantez içinde rastgele bir anahtar içeren değişkenimizin adını belirtiyorum.

Bu kadar. Aşağıdaki koda bakın ve sonunda her şeyi anlayacaksınız:

". $frases[$rand_frases] .""; ?>

3 tarafından yanıtla PunBB

  • İtibaren: Moskova, Sovkhoznay 3, apt. 98
  • Kayıtlı: 2014.07.07
  • Gönderiler: 3,775
  • Sadece PunBB'yi seviyorum:
  • 5 yıllar 6 aylar,
  • Seviyor: 463

Ynt: PHP'de diziden rastgele değer nasıl seçilir

Şimdi bazı rastgele dizi öğelerinin çıktısını alma alıştırması yapalım.

Tek bir öğe olması durumunda anahtarı döndürülür ve birden çok rastgele dizi öğesi olması durumunda bir dizi anahtar döndürülür. Bundan ekrana çıktıyı oluşturacağız.

Öncelikle 7 farklı isim gireceğimiz bir dizi oluşturalım.

Ardından, array_rand() fonksiyonunun çalışmasının girileceği bir değişken oluşturuyoruz. Ancak şimdi, bu fonksiyonun parantez içinde, ikinci argüman olarak "2" sayısını belirtiyoruz. Bu, 2 rastgele öğeye ihtiyacımız olduğu anlamına gelir.

Bu durumda işlevin sonucu, ana dizimizden iki rastgele öğe anahtarı içeren bir dizi olacaktır.

Bu nedenle, bunu ekranda görüntülerken, bunu dikkate almanız ve sadece değişkenin adını değil, değişkenin adını, ardından köşeli parantez ve dizi indeksini köşeli parantez içinde belirtmeniz gerekir. 2 öğemiz olduğundan, ilk durumda dizin , ikinci durumda olacaktır. (Dizi indekslemenin "0" ile başladığını unutmayın.)

Bu kadar. Size daha açık hale getirmek için koda bakın:

$isimler = dizi("Maşa", "Saşa", "Nadya", "Mila", "Andrey", "Sergey", "Anton"); $rand_names = array_rand($names,2); Eko "

".$isimler[$rand_names]." ve ".$names[$rand_names]."

";

Sonuç olarak, ekranda iki rastgele isim görüntülenecektir. Sayfa her yenilendiğinde adlar değişecektir.

Kaynak

eleman seç (11)

$ran = array(1,2,3,4); adında bir dizim var.

Bu diziden rastgele bir değer alıp bir değişkende saklamam gerekiyor, bunu nasıl yapabilirim?

Yanıtlar

Cevabımı @ÓlafurWaage'in özelliğine dayandırıyorum. Kullanmayı denedim ancak döndürülen nesneyi değiştirmeye çalıştığımda referans sorunlarıyla karşılaştım. Referansa göre geçmek ve geri dönmek için işlevini güncelledim. Yeni özellik:

&random_value(&$dizi, $varsayılan=null) ( $k = mt_rand(0, count($dizi) - 1); if (isset($dizi[$k])) ( return $dizi[$k]; ) başka ($varsayılanı döndür; ))

Bir nesneye referansları iletme/döndürme altındaki soruma bakın + daha fazla bilgi için bir nesneyi değiştirmek çalışmıyor

$değer = $dizi;

Aşağıdaki gibi dizinizden rastgele bir anahtar seçmek için array_rand işlevini kullanabilirsiniz.

$dizi = dizi("bir", "iki", "üç", "dört", "beş", "altı"); yankı $dizi;

veya rastgele bir dizin seçmek için Rand ve count işlevlerini kullanabilirsiniz.

$dizi = dizi("bir", "iki", "üç", "dört", "beş", "altı"); yankı $dizi;

$rastgele = $koştu;

Bir değere ihtiyacınız varsa, bir işlev olarak da kullanışlıdır.

function random_value($dizi, $varsayılan=null) ( $k = mt_rand(0, count($array) - 1); return isset($dizi[$k])? $dizi[$k]: $varsayılan; )

Seçiminizin herhangi bir güvenlik etkisi var mı? Öyleyse, random_int() ve array_keys() kullanın. (random_bytes() yalnızca PHP 7'dir, ancak PHP 5 için bir çoklu dolgu vardır).

function random_index(dizi $kaynak) ( $maks = sayım($kaynak) - 1; $r = random_int(0, $maks); $k = dizi_anahtarları($kaynak); dönüş $k[$r]; )

Başvuru:

$dizi = [ "elma" => 1234, "oğlan" => 2345, "kedi" => 3456, "köpek" => 4567, "echo" => 5678, "şans" => 6789 ]; $i = random_index($dizi); var_dump([$i, $dizi[$i]]);

işlev array_random($dizi, $tutar = 1) ( $keys = array_rand($dizi, $tutar); if ($tutar == 1) (döndür $dizi[$anahtarlar]; ) $sonuçlar = ; foreach ($anahtarlar) $anahtar olarak) ( $sonuçlar = $dizi[$anahtar]; ) $sonuçlar döndürür;)

Başvuru:

$items = ["foo", "bar", "baz", "lorem"=>"ipsum"]; dizi_random($öğeler); // "bar" array_random($item, 2); // ["foo", "ipsum"]

Birkaç not:

  • $amount, count($array) değerinden küçük veya eşit olmalıdır.
  • array_rand() anahtarları karıştırmaz (PHP 5.2.10'den beri, bakınız ), bu nedenle seçtiğiniz öğeler her zaman orijinal sırada olacaktır. Gerekirse shuffle() kullanın.

Düzenle: Laravel'in özelliği o zamandan beri gözle görülür şekilde büyüdü, bkz. Laravel 5.4"s Arr::random() . İşte Laravel'in yetişkin özelliğinden kaynaklanan biraz daha karmaşık bir şey:

işlev array_random($dizi, $sayı = null) ( $requested = ($number === null) ? 1: $sayı; $sayım = sayı($dizi); if ($istendi > $say) ( throw new \ RangeException("Öğeleri istediniz ($istendiniz), ancak yalnızca ($count) öğe mevcut."); ) if ($numara === null) ( return $dizi; ) if ((int) $number == = 0) ( dönüş ; ) $anahtarlar = (dizi) array_rand($dizi, $sayı); $sonuçlar = ;foreach ($anahtar olarak $anahtar) ( $sonuçlar = $dizi[$anahtar]; ) return $sonuçlar; )

Birkaç önemli nokta:

  • Yeterli kullanılabilir öğe yoksa bir istisna atın
  • array_random($array, 1) bir elemandan oluşan bir dizi döndürür (#19826)
  • Öğe sayısı için destek değeri "0" (Sadece saf ve basittir.

rand(1,N) ama dizi(a,b,c,..) hariç

Zaten bilmediğim yerleşik bir işlev var mı veya kendim uygulamam gerekiyor mu (nasıl?)?

GÜNCELLEME

Nitelikli bir çözüm, dışlanan dizinin boyutunun büyük olup olmadığına bakılmaksızın altın içermelidir.

Yerleşik bir işlev yoktur, ancak yapabilirsiniz Bunu yapmak için:

randWithout($from, $to, dizi $istisnalar) ( sort($exceptions); // break; işlevini foreach içinde güvenilir bir şekilde kullanmamıza izin verir $number = rand($from, $to - count($istisnalar)); / / veya mt_rand() foreach ($istisna olarak $istisnalar) ( if ($numara >= $istisna) ( $number++; // boşluğu telafi eder) else /*if ($number< $exception)*/ { break; } } return $number; }

Kafamda değil, bu yüzden cila kullanabilir - ama en azından varsayımsal olarak bile sonsuz bir döngü senaryosuna giremezsiniz.

Not: $İstisnalar varsa işlev bozulur egzoz aralığınız - örneğin, randWithout(1, 2, array(1,2)) veya randWithout(1, 2, array(0,1,2,3)) çağrılması makul bir şey üretmeyecektir (belli ki), ancak bu döndürülen sayının $from - $to aralığının dışında olması durumunda, yakalanması kolaydır.

$exceptions zaten sıralanmışsa, sort($exceptions); kaldırılabilir.

göz kamaştırıcı: algoritmanın biraz minimal görselleştirilmesi.

Böyle yerleşik bir işlev olduğunu düşünmüyorum; muhtemelen kendiniz kodlamanız gerekecek.

Bunu kodlamak için iki çözümünüz var:

  • Doğru değeri döndürene kadar Rand() veya mt_rand() işlevini çağırmak için bir döngü kullanın
    • bu, Rand() öğesini birden çok kez çağırmak anlamına gelir, en kötü durum
    • ancak N büyükse ve çok fazla yasak değeriniz yoksa bu iyi çalışmalıdır.
  • Yalnızca yasal değerleri içeren bir dizi oluşturun
    • Ve kullan dizi_rand ondan bir değer seçmek için
    • N küçükse hangisi iyi çalışır

Neye ihtiyacınız olduğuna ve neden bu yaklaşım ilginç bir alternatif olabilir.

$sayılar = dizi_diff(aralık(1, N), dizi(a, b, c)); // Ya (gerçek bir yanıt değil, ancak durumunuza bağlı olarak yararlı olabilir) shuffle($numbers); // $numbers artık sizi ilgilendiren tüm sayıları içeren rastgele sıralanmış bir dizidir // Veya: $x = $numbers; // $x artık ilgilendiğiniz sayı kümesinden seçilen rastgele bir sayıdır

Bu nedenle, her seferinde bir dizi potansiyel sayı oluşturmanız gerekmiyorsa, ancak bir kez bir dizi oluşturup aynı kümeden bir grup rastgele sayı seçerseniz, bu iyi bir yol olabilir.

En kolay yol …

M = N - # istisna uzunluğundaki bitişik bir dizide rastgele bir konum seçebilmeniz ve onu deliklerle orijinal diziye kolayca eşleyebilmeniz için bir dizi eksik konum hesaplamanız gerekir. Bu, geçirilen diziye eşit zaman ve alan gerektirecektir. Php'yi yerdeki bir delikten bilmiyorum, bu yüzden yarı-psudo kod metni örneğini bağışlayın.

  1. İstisnalar dizisiyle aynı uzunlukta yeni bir Offset dizisi yapın.
  2. Offset [i]'de, ilk dizini orijinal dizideki i öğelerini kaçıracak boş olmayan hayali bir dizide saklar.
  3. Şimdi rastgele bir öğe seçin. Rastgele bir sayı seçin, r , 0..M'de kalan eleman sayısı.
  4. Ofset[i] olan i'yi bulun<= r < Offest это легко с бинарным поиском
  5. r + i döndür

Şimdi, bu sadece bir taslak, dizilerin uçlarıyla ve eğer bir şey 0 veya 1 şeklinde indekslenirse ve tüm bu jazz ile ilgilenmeniz gerekecek. Akıllıysanız, Offset dizisini orijinalden anında hesaplayabilirsiniz, ancak bu biraz daha az açıktır.

Belki bir cevap için çok geç, ama bir sayı dışında rastgele bir kimliğe dayalı bir veritabanından rastgele veri almaya çalışırken bu kod parçasını aklımda bir yerde buldum.

$excludedData = dizi(); // Bu sizin hariç tuttuğunuz sayıdır $maxVal = $this->db->count_all_results("game_pertanyaan"); // Veritabanıma göre maksimum sayıyı al $randomNum = rand(1, $maxVal); // İlk başlatmayı yap, sanırım bunu doğrudan while > in_array parametresine koyabilirsin, işe yarıyor gibi görünüyor, bu sana kalmış while (in_array($randomNum, $excludedData)) ( $randomNum = rand(1,) $maxVal); ) $randomNum; //Seçtiğiniz bir sayı hariç rastgele numaranız

Rastgele sayılar, özellikle güvenlik sistemleri söz konusu olduğunda, programlamanın ayrılmaz bir parçasıdır. Örneğin kriptografi, tahmin edilemeyen sayılar üretmek için rastgele değerler üretmeye dayanır. Elbette PHP'de rastgele sayılar çok büyük bir rol oynar: onların yardımıyla belirteçler, tuz ve diğer değerleri üretebiliriz.

Rastgele sayı üretimi özel algoritmalara dayanmaktadır. Algoritmanın başlayacağı girdi parametresi, rastgele bir değer veya önceden belirlenmiş bir değer olabilir.

Bu yazıda rasgele sayılar hakkında konuşacağız: nasıl üretildikleri ve nerede kullanılabilecekleri.

Rastgele sayılar kullanma

Rastgele sayılar PHP'de büyük bir rol oynar, çünkü çok sık çeşitli amaçlar için kullanılır. Temel olarak, güvenlikle ilgilidirler. Onlara dayanarak, CSRF belirteçleri, API anahtarları, kimlik doğrulama değerleri, şifreleri sıfırlama değerleri ve çok daha fazlası oluşturulur. Bütün bunlar, ortaya çıkan değeri tahmin etmeyi imkansız kılmak için yapılır.

Rastgele değerler kullanmanın en önemli örnekleri şunlardır:

  • Kriptografi için tuz üretimi- Kural olarak, tek yönlü şifreleme ve ayrıca şifreleri karıştırmak için rastgele bir tuz numarası kullanılır. Bu rastgele değer, kriptografide bir başlatma vektörü olarak kullanılır.
  • Oturum kimliği gibi rastgele değerler oluşturma- PHP, güvenliğin önce geldiği çok sayıda uygulama oluşturmak için kullanılır. Birçok işlev, oturumlarla ve oluşturulan oturum kimlikleriyle çalışmaya dayanır.
  • Tahmin edilmesi neredeyse imkansız olan kimlik doğrulama belirteçlerinin üretilmesi- birçok PHP uygulaması, özel API arayüzleri aracılığıyla diğer sistemlerle çalışmayı temel alır. Genellikle, API'yi kullanmadan önce kimlik doğrulama sürecinden geçmeniz gerekir. Jetonlar için tahmin edilmesi zor değerler elde etmek çok zordur. Bu nedenle bu problemlerde rastgele sayılar kullanılır.

Rastgele sayı üreteçleri

Yukarıda açıklanan durumlarda kullanılan rastgele sayılar, sözde oluşturucular tarafından PHP'de üretilir. Mevcut birkaç algoritma vardır:

    lcg_value() işlevi kullanılırken doğrusal uyumlu yöntem.

    mt_rand() işlevi tarafından kullanılan Mersenne girdabı.

    C dilinde benzer bir işlevi kullanan rand() işlevi.

Aslında, bu işlevler rastgele sayılar döndürmez, ancak rastgele sayılar gibi görünecek şekilde dağıtılmış sayılar döndürür. Bu sayıların sırası, uygulanan algoritma içindeki temel rastgele sayıya bağlıdır.

Jeneratörler için temel sayılar

Baz sayılar veya bu tür sayıların vektörleri, rasgele sayılar üretmek için kullanılan veri kümeleridir. Sözde rastgele sayı üreteçleri yalnızca onlara dayalı olarak çalışır. Bir saldırgan bu temel sayıyı biliyorsa, gelecekte rastgele sayılarınızın değerlerini tahmin edebilecektir.

PHP'de temel sayıları iki şekilde ayarlayabilirsiniz. Birincisi mt_srand() işlevini kullanmaktır. Bu yöntem esas olarak rastgele bir serinin birim testlerinde kullanılır. İkinci yol, PHP'nin temel sayıları kendisinin üretmesine izin vermektir. 4.2 sürümünden itibaren PHP bu yeteneği sağlar. Daha sonra, Mersenne Vortex rastgele sayılar üretmek için kullanılacaktır.

PHP, işletim sistemine bağlı olarak bir temel sayı üretir. Linux platformlarında, /dev/urandom içinde mcrypt_create_iv() veya openssl_pseudo_random_bytes() işlevlerini kullanabilirsiniz. Windows, openssl_pseudo_random_bytes() ve mcrypt_create_iv() işlevleri aracılığıyla erişilebilen özel bir sözde oluşturucu sağlar.

Sonuç

Rastgele sayılar, güvenli web uygulamaları oluşturmada büyük bir rol oynadığından, nasıl çalıştıkları hakkında daha fazla bilgi sahibi olmamız gerekir. Sözde üreteçler için temel sayılar oluşturmak istiyorsanız, yöntemlerinizin güvenilir olduğundan emin olun.