Ablakok.  Vírusok.  Jegyzetfüzetek.  Internet.  hivatal.  Segédprogramok.  Drivers

elem kiválasztása (11)

Van egy $ran = array(1,2,3,4) nevű tömböm;

Ebből a tömbből véletlenszerű értéket kell kapnom, és azt egy változóban kell tárolnom, hogyan tudom ezt megtenni?

Válaszok

Válaszomat @ÓlafurWaage funkciójára alapozom. Megpróbáltam használni, de hivatkozási problémákba ütköztem, amikor megpróbáltam módosítani a visszaadott objektumot. Frissítettem a funkcióját, hogy referenciaként adja át és térjen vissza. Új funkció:

Függvény &random_value(&$array, $default=null) ( $k = mt_rand(0, count($array) - 1); if (isset($array[$k])) ( return $array[$k]; ) else ($alapértelmezett érték visszaadása; ) )

Megszerzéséért további információ lásd a kérdésemet az Objektumra való hivatkozások átadása/visszaadása alatt + az objektum módosítása nem működik

$érték = $tömb;

Az array_rand függvény segítségével kiválaszthat egy véletlenszerű kulcsot a tömbből az alábbiak szerint.

$tömb = array("egy", "kettő", "három", "négy", "öt", "hat"); echo $tömb;

vagy használhatja a rand és a count függvényeket egy véletlenszerű index kiválasztásához.

$tömb = array("egy", "kettő", "három", "négy", "öt", "hat"); echo $tömb;

$véletlen = $futott;

Funkcióként is hasznos, ha értékre van szüksége.

Funkció random_value($array, $default=null) ( $k = mt_rand(0, count($array) - 1); return isset($array[$k])? $array[$k]: $alapértelmezett; )

Van a választásának biztonsági vonatkozásai? Ha igen, használja a random_int() és array_keys() . (A random_bytes() csak PHP 7, de van egy polifill a PHP 5-höz).

Funkció random_index(tömb $forrás) ( $max = count($source) - 1; $r = random_int(0, $max); $k = array_keys($source); return $k[$r]; )

Alkalmazás:

$tömb = [ "alma" => 1234, "fiú" => 2345, "macska" => 3456, "kutya" => 4567, "visszhang" => 5678, "szerencse" => 6789 ]; $i = random_index($tömb); var_dump([$i, $tömb[$i]]);

Függvény array_random($tömb, $összeg = 1) ( $kulcsok = array_rand($tömb, $összeg); if ($összeg == 1) ( return $tömb[$kulcsok]; ) $eredmények = ; foreach ($kulcsok $kulcsként) ( $eredmények = $tömb[$kulcs]; ) $eredményeket adja vissza; )

Alkalmazás:

$items = ["foo", "bar", "baz", "lorem"=>"ipsum"]; array_random($elemek); // "sáv" array_random($items, 2); // ["foo", "ipsum"]

Néhány megjegyzés:

  • $amount legyen kisebb vagy egyenlő, mint count($array) .
  • Az array_rand() nem keveri össze a kulcsokat (a PHP 5.2.10 óta, lásd ), így a kiválasztott elemek mindig az eredeti sorrendben lesznek. Ha szükséges, használja a shuffle()-t.

szerkesztés: A Laravel funkciója észrevehetően nőtt azóta, lásd Laravel 5.4"s Arr::random() . Itt van valami, ami egy kicsit összetettebb, ami a Laravel felnőtt funkciójából fakad:

Függvény array_random($tömb, $szám = null) ( $requested = ($szám === null) ? 1: $szám; $count = count($tömb); if ($requested > $count) ( dob új \ RangeException("Kért ($kérte) elemeket, de csak ($count) elemek állnak rendelkezésre."); ) if ($szám === null) ( return $tömb; ) if ((int) $szám == = 0) ( return ; ) $kulcsok = (tömb) array_rand($tömb, $szám); $eredmények = ; foreach ($kulcsok $kulcsként) ( $eredmények = $tömb[$kulcs]; ) return $eredmények; )

Néhány kiemelés:

  • Adjon kivételt, ha nincs elég elérhető elem
  • Az array_random($array, 1) egy elemből álló tömböt ad vissza (#19826)
  • Támogassa a „0” értéket az elemek számához (ez csak tiszta és egyszerű.

Párszor megkérdezték, hogyan csinálom idézetek véletlenszerű kimenete a webhelyén a blokkban " Intelligens idézetek". Továbbá sikerült rájönnöm, hogy itt a probléma az emberek félreértése, hogyan lehet véletlenszerű elemet szerezni a tömbből php-ban. A feladat egyszerű, de ennek ellenére, mivel kérdések merülnek fel, meg kell válaszolni őket.

Mindjárt megadom a kódot. Tegyük fel, hogy van egy tömb idézőjelkészlettel. És ki kell választani közülük egyet véletlenszerűen, és ki kell adnia:

$idézőjelek = array(); // Üres tömb inicializálása
$quotes = "Légy figyelmes a gondolataira, ezek a cselekvések kezdetei."; // Első idézet
$quotes = "Nem a legokosabb vagy a legerősebb él túl, hanem a legfogékonyabb a változásra."; // Második idézet
$quotes = "Az élet egy hegy: menj fel lassan, menj le gyorsan."; // Harmadik idézet
$quotes = "Az emberek nem akarnak gazdagok lenni, az emberek gazdagabbak akarnak lenni, mint mások."; // Negyedik idézet
$szám = mt_rand(0, count($idézőjelek) - 1); // Vegyünk egy véletlen számot 0-tól (tömb hossza mínusz 1) beleértve
echo $idézőjelek[$szám]; // Kimeneti idézet
?>

A kulcspont az véletlen számot kapni. Nincs más dolgod, mint a megfelelő határok felállítása. Ha egy véletlenszerű elemet kell kiválasztania a tömb teljes hosszában, akkor ez innen származik 0 előtt ( tömb hossza mínusz 1). És akkor csak húzza ki az elemet adott véletlen indexű tömbből.

Ami az idézetekkel kapcsolatos feladatot illeti, jobb, ha adatbázisban tárolja őket. Elvileg, ha az oldal nagyon egyszerű, akkor megteheti szöveges fájl. De ha adatbázisban, akkor jobb használni RAND()És HATÁR V SQL lekérdezés hogy azonnal egyetlen véletlenszerű árajánlatot kapjon az adatbázisból.

A véletlenszerű számok a programozás szerves részét képezik, különösen, ha biztonsági rendszerekről van szó. Például a kriptográfia véletlenszerű értékek generálására támaszkodik, hogy olyan számokat hozzon létre, amelyeket nem lehet előre megjósolni. Természetesen a PHP-ben óriási szerepe van a véletlen számoknak: segítségével tokeneket, sót és egyéb értékeket generálhatunk.

A véletlenszám-generálás speciális algoritmusokon alapul. A bemeneti paraméter, amelytől az algoritmus elindul, lehet véletlenszerű vagy előre meghatározott érték.

Ebben a cikkben a véletlen számokról fogunk beszélni: hogyan jönnek létre és hol használhatók.

Véletlen számok használata

A véletlen számok óriási szerepet játszanak a PHP-ben, mert nagyon gyakran használják különféle célokra. Alapvetően a biztonsággal kapcsolatosak. Ezek alapján CSRF tokenek, API kulcsok, hitelesítési értékek, jelszavak visszaállításához szükséges értékek és még sok más jön létre. Mindezt azért teszik, hogy a kapott értéket lehetetlen megjósolni.

A véletlenszerű értékek használatának legfontosabb példái a következők:

  • Só előállítása titkosításhoz- rendszerint véletlenszerű sószámot használnak az egyirányú titkosításhoz, valamint a jelszavak kivonatozásához. Ezt a véletlenszerű értéket inicializálási vektorként használják a kriptográfiában.
  • Véletlenszerű értékek, például munkamenet-azonosító generálása- A PHP-t nagyszámú alkalmazás létrehozására használják, ahol a biztonság az első. Számos funkció a munkamenetekkel és a generált munkamenet-azonosítókkal való együttműködésen alapul.
  • Hitelesítési tokenek generálása, amelyeket szinte lehetetlen megjósolni- sok PHP alkalmazások más rendszerekkel való együttműködésen alapulnak speciális API interfészeken keresztül. Általában az API használata előtt át kell mennie a hitelesítési folyamaton. A tokenek nehezen kitalálható értékeit nagyon nehéz megtalálni. Ezért használnak véletlen számokat ezekben a feladatokban.

Véletlenszám-generátorok

A fent leírt esetekben használt véletlenszámokat a PHP-ben pszeudogenerátorok generálják. Számos algoritmus áll rendelkezésre:

    Lineáris kongruens metódus az lcg_value() függvény használatakor.

    Mersenne vortex, az mt_rand() függvény által használt.

    A rand() függvény, amely hasonló függvényt használ a C nyelvben.

Valójában ezek a függvények nem véletlen számokat adnak vissza, hanem olyan számokat, amelyek úgy vannak elosztva, hogy véletlenszerűnek tűnjenek. Ezeknek a számoknak a sorrendje a mögöttes véletlen számtól függ az implementált algoritmuson belül.

Generátorok alapszámai

Az alapszámok vagy az ilyen számok vektorai olyan adathalmazok, amelyeket véletlen számok generálására használnak. A pszeudo-véletlenszám-generátorok csak ezek alapján működnek. Ha egy támadó ismeri ezt az alapszámot, akkor a jövőben képes lesz megjósolni a véletlen számok értékét.

A PHP-ben kétféleképpen állíthatja be az alapszámokat. Az első az mt_srand() függvény használata. Ezt a módszert főleg véletlenszerű sorozatok egységtesztjénél alkalmazzák. A második mód az, hogy hagyjuk, hogy a PHP maga generálja az alapszámokat. A 4.2-es verziótól kezdve a PHP biztosítja ezt a lehetőséget. Ezt követően a Mersenne Vortexet véletlen számok generálására fogják használni.

A PHP alapszámot generál attól függően operációs rendszer. Linux platformokon használhatja az mcrypt_create_iv() vagy openssl_pseudo_random_bytes() függvényeket a /dev/urandom könyvtárban. A Windows egy speciális pszeudogenerátort biztosít, amely az openssl_pseudo_random_bytes() és az mcrypt_create_iv() függvényeken keresztül érhető el.

Eredmény

Mivel a véletlen számok óriási szerepet játszanak a biztonságos webalkalmazások felépítésében, többet kell tudnunk működésükről. Ha saját maga akar alapszámokat generálni pszeudogenerátorokhoz, akkor győződjön meg arról, hogy módszerei megbízhatóak.

rand(1,N), de nem tartalmazza a tömb(a,b,c,..)

van már beépített funkció, amit nem ismerek, vagy magamnak kell megvalósítani (hogyan?)?

FRISSÍTÉS

A minősített megoldásnak aranyszínűnek kell lennie, függetlenül attól, hogy a kizárt tömb mérete nagy-e vagy sem.

Nincs beépített funkció, csak te tudsz csináld:

A randWithout($from, $to, tömb $kivételek) függvény ( sort($exceptions); // lehetővé teszi a break használatát; a foreachben megbízhatóan $number = rand($from, $to - count($exceptions)); / / vagy mt_rand() foreach ($exceptions mint $kivétel) ( if ($szám >= $kivétel) ( $szám++; // pótolja a hiányt ) else /*if ($szám< $exception)*/ { break; } } return $number; }

Nem az én fejemben van, szóval ráférne a polírozás – de legalább még hipotetikusan sem kerülhetsz végtelen ciklusba.

jegyzet: A függvény megszakad, ha $kivételek vannak kipufogók a tartományod - például a randWithout(1, 2, array(1,2)) vagy a randWithout(1, 2, array(0,1,2,3)) meghívása nem eredményez semmi ésszerűt (nyilvánvalóan), de ebben Ebben az esetben a visszaadott szám kívül esik a $tól - $to tartományon, így könnyen megfogható.

Ha a $kivételek már garantáltan rendezve vannak, akkor sort($exceptions); eltávolítható.

látványelem: az algoritmus kissé minimális megjelenítése.

Szerintem nincs ilyen beépített funkció; valószínűleg magának kell kódolnia.

Ennek kódolásához két megoldása van:

  • Használjon ciklust a rand() vagy mt_rand() meghívásához, amíg vissza nem adja a megfelelő értéket
    • ami a rand() többszöri meghívását jelenti, legrosszabb esetben
    • de ennek jól kell működnie, ha N nagy, és nincs sok tiltott érték.
  • Hozzon létre egy tömböt, amely csak jogi értékeket tartalmaz
    • És használja tömb_rand hogy válasszon ki belőle egy értéket
    • ami jól működik, ha N kicsi

Attól függően, hogy mire van szüksége, és miért lehet ez a megközelítés érdekes alternatíva.

$számok = array_diff(tartomány(1, N), tömb(a, b, c)); // Vagy (nem igazi válasz, de hasznos lehet, a körülményektől függően) shuffle($numbers); // A $numbers most egy véletlenszerűen rendezett tömb, amely tartalmazza az összes számot, amely érdekli // Vagy: $x = $számok; // A $x egy véletlenszerű szám, amelyet az Önt érdeklő számok közül választottak ki

Tehát, ha nem kell minden alkalommal potenciális számokat generálnia, hanem egyszer generál egy halmazt, majd kiválaszt egy csomó véletlenszerű számot ugyanabból a halmazból, akkor ez egy jó út.

A legegyszerűbb módja…

Ki kell számítania a hiányzó helyek tömbjét, hogy kiválaszthasson egy véletlenszerű pozíciót egy M = N - kivételek # hosszúságú összefüggő tömbben, és könnyen visszaképezhesse az eredeti tömbre lyukakkal. Ehhez az átadott tömbnek megfelelő időre és helyre lesz szüksége. Nem ismerem a php-t lyukból a földbe, szóval elnézést a félig psudo kód szöveges példáért.

  1. Hozzon létre egy új Offset tömböt, amely ugyanolyan hosszúságú, mint a Kivételek tömb.
  2. Az [i] eltolásban az első indexet egy képzeletbeli nem üres tömbben tárolja, amelyből hiányoznának az i elemek az eredeti tömbből.
  3. Most válasszon ki egy véletlenszerű elemet. Válasszon egy véletlenszámot, r , 0..M-ben a hátralévő elemek számában.
  4. Keresse meg azt az eltolást[i]<= r < Offest это легко с бинарным поиском
  5. Return r + i

Nos, ez csak egy vázlat, foglalkoznod kell a tömbök végeivel, és ha valami 0 vagy 1 formában van indexelve, és minden jazz. Ha okos vagy, ténylegesen ki tudja számítani az eltolási tömböt az eredetiből, de ez egy kicsit kevésbé egyértelmű.

Talán már túl késő a válaszhoz, de ezt a kódrészletet valahol a fejemben találtam, miközben véletlenszerű adatokat próbáltam lekérni egy adatbázisból egy véletlenszerű azonosító alapján, kivéve néhány számot.

$excludedData = array(); // Ez a kizárt számod $maxVal = $this->db->count_all_results("game_pertanyaan"); // A maximális szám lekérése az adatbázisom alapján $randomNum = rand(1, $maxVal); // Tedd meg az első beavatást, azt hiszem tudsz tedd ezt közvetlenül a while > in_array paraméterbe, úgy tűnik, ez is működik, ez rajtad múlik while (in_array($randomNum, $excludedData)) ( $randomNum = rand(1, $maxVal); ) $randomNum; // Az Ön véletlen száma, kivéve néhány kiválasztott számot

Ha hibát észlel, jelöljön ki egy szövegrészt, és nyomja meg a Ctrl + Enter billentyűket
OSSZA MEG: