Pár slov o generovaní náhodných čísel v PHP. Ako vybrať náhodnú hodnotu z poľa v náhodnej hodnote PHP

  • 03.11.2019

Párkrát sa ma pýtali, ako to robím náhodný výstup úvodzoviek na vašej stránke v bloku " Inteligentné ponukyĎalej sa mi podarilo zistiť, že problém je tu v nepochopení ľudí, ako získať náhodný prvok z poľa v php. Úloha je jednoduchá, no napriek tomu, keďže vznikajú otázky, je potrebné na ne odpovedať.

Hneď vám dám kód. Povedzme, že existuje pole so sadou úvodzoviek. A musíte si vybrať jeden náhodný z nich a výstup:

$úvodzovky = pole(); // Inicializuje prázdne pole
$quotes = "Buďte pozorní na svoje myšlienky, sú začiatkom činov."; // Prvý citát
$quotes = "Prežijú nie tí najmúdrejší alebo najsilnejší, ale tí, ktorí sú najviac vnímaví k zmenám."; // Druhý citát
$quotes = "Život je hora: pomaly stúpaj, rýchlo klesáš."; // Tretí citát
$quotes = "Ľudia nechcú byť bohatí, ľudia chcú byť bohatší ako ostatní."; // Štvrtý citát
$číslo = mt_rand(0, počet($úvodzovky) - 1); // Vezmite náhodné číslo od 0 do (dĺžka poľa mínus 1) vrátane
echo $citáty[$číslo]; // Výstupná ponuka
?>

Kľúčovým bodom je získanie náhodného čísla. Stačí, ak si nastavíte správne hranice. Ak potrebujete vybrať náhodný prvok po celej dĺžke poľa, potom je to z 0 predtým ( dĺžka poľa mínus 1). A potom už len vytiahnuť prvok z poľa s daným náhodným indexom.

Pokiaľ ide o úlohu s úvodzovkami, je lepšie ich uložiť do databázy. V zásade, ak je stránka veľmi jednoduchá, potom je to možné v textovom súbore. Ale ak v databáze, potom je lepšie použiť RAND() a LIMIT v SQL dotaz aby ste okamžite dostali jedinú a náhodnú cenovú ponuku z databázy.

  • Od:
  • Registrovaný: 2014.07.07
  • Príspevky: 3,775
  • Mám rád PunBB:
  • 5 roky, 6 mesiace,
  • Páči sa: 463

Téma: Ako vybrať náhodnú hodnotu z poľa v PHP

Pomocou tejto funkcie môžeme vybrať náhodný prvok (alebo prvky) poľa. Áno, presne ten prvok alebo prvky! Môže to byť jeden prvok alebo ich môže byť niekoľko. Všetko závisí od úlohy, ktorej čelíte.

Tu si však treba uvedomiť, že funkcia nevráti hodnotu prvku, ale jeho kľúč (alebo klávesy, ak je prvkov viacero).

Ako parametre v zátvorkách funkcia berie: názov poľa, s ktorým pracujeme, a počet prvkov, ktoré sa majú vybrať.

Vo všeobecnosti je všetko jednoduché! A bude to ešte jednoduchšie, keď sa na to všetko pozrieme na príkladoch.

Začnime výberom jedného náhodného prvku z poľa.

2 Odpovedať od PunBB

  • Od: Moskva, Sovchoznay 3, apt. 98
  • Registrovaný: 2014.07.07
  • Príspevky: 3,775
  • Mám rád PunBB:
  • 5 roky, 6 mesiace,
  • Páči sa: 463

Predstavme si, že niekde v hornej časti našej stránky chceme zobraziť nejaké citáty. Samozrejme, citáty sa musia zmeniť. Zakaždým, keď navštívite vašu stránku, chcete, aby používateľ videl novú cenovú ponuku.

Ako ste pravdepodobne uhádli, najjednoduchší spôsob, ako to implementovať, je vložiť všetky dostupné úvodzovky do poľa a potom vybrať náhodný prvok z tohto poľa a zobraziť ho na obrazovke.

Čím viac úvodzoviek máte v poli, tým je menšia pravdepodobnosť, že sa budú opakovať.

Ale napríklad sa nebudem veľmi obťažovať a do poľa dám 7 výrokov.

Ďalej si budem musieť vytvoriť premennú, do ktorej zapíšem výsledok funkcie array_rand (). V zátvorkách bude mať táto funkcia dva argumenty: názov nášho poľa a počet náhodných prvkov, ktoré potrebujeme.

Ako som už povedal, funkcia nevracia hodnotu prvku, ale jeho kľúč (alebo číslo v zozname). Kľúč náhodného prvku bude teda uložený v premennej.

Potom už len potrebujem zobraziť hodnotu požadovaného prvku na obrazovke. Za týmto účelom uvediem názov poľa a v hranatých zátvorkách názov našej premennej, ktorá obsahuje náhodný kľúč.

To je všetko. Pozrite sa na kód nižšie a myslím, že konečne všetko pochopíte:

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

3 Odpovedať od PunBB

  • Od: Moskva, Sovchoznay 3, apt. 98
  • Registrovaný: 2014.07.07
  • Príspevky: 3,775
  • Mám rád PunBB:
  • 5 roky, 6 mesiace,
  • Páči sa: 463

Re: Ako vybrať náhodnú hodnotu z poľa v PHP

Teraz si precvičme výstup niektorých prvkov náhodného poľa.

V prípade jedného prvku sa vráti jeho kľúč a v prípade viacerých prvkov náhodného poľa sa vráti pole kľúčov. Z toho budeme stavať na výstupe na obrazovku.

Najprv si vytvoríme pole, do ktorého zadáme 7 rôznych mien.

Ďalej vytvoríme premennú, do ktorej bude zadaná práca funkcie array_rand(). Až teraz v zátvorke tejto funkcie uvádzame číslo „2“ ako druhý argument. To znamená, že potrebujeme 2 náhodné prvky.

Výsledkom funkcie v tejto situácii bude pole obsahujúce dva náhodné kľúče prvkov z nášho hlavného poľa.

Preto pri zobrazovaní na obrazovke to musíte vziať do úvahy a v hranatých zátvorkách uviesť nielen názov premennej, ale aj názov premennej, potom hranaté zátvorky a index poľa. Keďže máme 2 prvky, v prvom prípade bude index , a v druhom . (Pamätajte, že indexovanie poľa začína na "0".)

To je všetko. Pozrite sa na kód, aby vám to bolo jasnejšie:

$names = array("Masha", "Sasha", "Naďa", "Mila", "Andrey", "Sergey", "Anton"); $rand_names = array_rand($names,2); ozvena"

".$names[$rand_names]." a ".$names[$rand_names]."

";

V dôsledku toho sa na obrazovke zobrazia dve náhodné mená. Pri každom obnovení stránky sa názvy zmenia.

Zdroj

vybrať prvok (11)

Mám pole s názvom $ran = array(1,2,3,4);

Potrebujem získať náhodnú hodnotu z tohto poľa a uložiť ju do premennej, ako to môžem urobiť?

Odpovede

Svoju odpoveď zakladám na funkcii @ÓlafurWaage. Skúsil som to použiť, ale pri pokuse o zmenu vráteného objektu som narazil na problémy s referenciami. Aktualizoval som jej funkciu, aby prechádzala a vracala sa podľa odkazu. Nová funkcia:

Funkcia &random_value(&$pole, $default=null) ( $k = mt_rand(0, počet($pole) - 1); if (isset($pole[$k])) ( return $pole[$k]; ) else ( return $default; ) )

Viac informácií nájdete v mojej otázke v časti Odovzdávanie/vracanie odkazov na objekt + úprava objektu nefunguje

$hodnota = $pole;

Na výber náhodného kľúča z poľa môžete použiť funkciu array_rand, ako je uvedené nižšie.

$pole = pole("jeden", "dva", "tri", "štyri", "päť", "šesť"); echo $array;

alebo môžete použiť funkcie rand a count na výber náhodného indexu.

$pole = pole("jeden", "dva", "tri", "štyri", "päť", "šesť"); echo $array;

$náhodný = $beh;

Je to tiež užitočné ako funkcia, ak potrebujete hodnotu.

Funkcia random_value($array, $default=null) ( $k = mt_rand(0, count($array) - 1); return isset($array[$k])? $array[$k]: $default; )

Má váš výber nejaké bezpečnostné dôsledky? Ak áno, použite random_int() a array_keys() . (random_bytes() je len PHP 7, ale existuje polyfill pre PHP 5).

Funkcia random_index(pole $source) ( $max = počet ($zdroj) - 1; $r = random_int(0, $max); $k = array_keys($source); return $k[$r]; )

Aplikácia:

$array = [ "jablko" => 1234, "chlapec" => 2345, "mačka" => 3456, "pes" => 4567, "echo" => 5678, "šťastie" => 6789 ]; $i = náhodný_index($pole); var_dump([$i, $pole[$i]]);

Funkcia array_random($pole, $suma = 1) ( $keys = array_rand($pole, $suma); if ($suma == 1) ( return $pole[$keys]; ) $results = ; foreach ($keys ako $key) ( $results = $pole[$key]; ) vrátiť $results; )

Aplikácia:

$items = ["foo", "bar", "baz", "lorem"=>"ipsum"]; pole_random($položky); // "bar" array_random($items, 2); // ["foo", "ipsum"]

Pár poznámok:

  • $suma musí byť menšia alebo rovná count($array) .
  • array_rand() nezamieša kľúče (od PHP 5.2.10, pozri ), takže prvky, ktoré vyberiete, budú vždy v pôvodnom poradí. V prípade potreby použite shuffle().

upraviť: Funkcia Laravelu sa odvtedy výrazne rozrástla, pozri Arr::random() Laravelu 5.4". Tu je niečo trochu zložitejšie, vychádzajúce z funkcie Laravel pre dospelých:

Funkcia array_random($pole, $číslo = null) ( $requested = ($number === null) ? 1: $number; $count = count($array); if ($requested > $count) (hodiť nové \ RangeException("Požadovali ste ($požadované) položky, ale k dispozícii sú iba ($count) položky."); ) if ($number === null) ( return $array; ) if ((int) $number == = 0) ( return ; ) $keys = (pole) array_rand ($pole, $číslo); $results = ; foreach ($keys ako $key) ( $results = $pole[$key]; ) return $results; )

Niekoľko zaujímavostí:

  • Vyhoďte výnimku, ak nie je dostatok dostupných položiek
  • array_random($array, 1) vráti pole jedného prvku (#19826)
  • Podporná hodnota "0" pre počet prvkov (Je to len čisté a jednoduché.

rand(1,N), ale s výnimkou poľa(a,b,c,..)

existuje už vstavaná funkcia, ktorú nepoznám alebo ju musím implementovať sám (ako?)?

AKTUALIZOVAŤ

Kvalifikované riešenie musí mať zlato bez ohľadu na to, či je veľkosť vylúčeného poľa veľká alebo nie.

Nie je tam vstavaná funkcia, ale vy môžeš urob to:

Funkcia randWithout($from, $to, pole $výnimky) ( sort($exceptions); // nám umožňuje použiť break; vo foreach spoľahlivo $number = rand($from, $to - count($exceptions)); / / alebo mt_rand() foreach ($exceptions as $exception) ( if ($number >= $exception) ( $number++; // doplňte medzeru ) else /*if ($number< $exception)*/ { break; } } return $number; }

Nie je to v mojej hlave, takže by to mohlo použiť leštidlo - ale aspoň nemôžete skončiť v scenári nekonečnej slučky, dokonca ani hypoteticky.

Poznámka: Funkcia sa preruší, ak $výnimky výfuky váš rozsah – napríklad volanie randWithout(1, 2, array(1,2)) alebo randWithout(1, 2, array(0,1,2,3)) neprinesie nič rozumné (samozrejme), ale v tomto v prípade, že sa číslo vráti, bude mimo rozsahu $od - $do, takže je ľahké ho zachytiť.

Ak je zaručené, že $výnimky sú už zoradené, sort($exceptions); možno odstrániť.

pastva pre oči: trochu minimálna vizualizácia algoritmu.

Nemyslím si, že existuje taká vstavaná funkcia; pravdepodobne si to budete musieť naprogramovať sami.

Na kódovanie máte dve riešenia:

  • Použite cyklus na volanie rand() alebo mt_rand(), kým nevráti správnu hodnotu
    • čo znamená volanie rand() viackrát, v najhoršom prípade
    • ale malo by to fungovať, ak je N veľké a nemáte veľa zakázaných hodnôt.
  • Vytvorte pole obsahujúce iba zákonné hodnoty
    • A používať pole_rand aby ste z neho vybrali jednu hodnotu
    • čo bude fungovať dobre, ak je N malé

V závislosti od toho, čo potrebujete a prečo môže byť tento prístup zaujímavou alternatívou.

$cisla = pole_rozdiel(rozsah(1, N), pole(a, b, c)); // Buď (nie je to skutočná odpoveď, ale môže byť užitočná, v závislosti od vašich okolností) shuffle($numbers); // $numbers je teraz náhodne zoradené pole obsahujúce všetky čísla, ktoré vás zaujímajú // Alebo: $x = $numbers; // $x je teraz náhodné číslo vybrané zo skupiny čísel, ktoré vás zaujímajú

Ak teda nepotrebujete zakaždým generovať množinu potenciálnych čísel, ale množinu vygenerujete raz a potom z tej istej množiny vyberiete množinu náhodných čísel, môže to byť dobrý spôsob.

Najjednoduchší spôsob…

Musíte vypočítať pole chýbajúcich miest, aby ste mohli vybrať náhodnú pozíciu v súvislom poli dĺžky M = N - počet výnimiek a jednoducho ju namapovať späť na pôvodné pole s dierami. To si bude vyžadovať čas a priestor rovný odovzdanému poľu. Neviem php z diery v zemi, tak pardon za semi-psudo kódový textový príklad.

  1. Vytvorte nové pole Offset rovnakej dĺžky ako pole Exceptions.
  2. v Offset [i] uloží prvý index do imaginárneho neprázdneho poľa, ktorému by v pôvodnom poli chýbali prvky i.
  3. Teraz vyberte náhodný prvok. Vyberte náhodné číslo, r , v 0..M počet zostávajúcich prvkov.
  4. Nájsť ten posun[i]<= r < Offest это легко с бинарным поиском
  5. Návrat r + i

Toto je len náčrt, budete sa musieť vysporiadať s koncami polí a ak je niečo indexované vo forme 0 alebo 1 a všetok ten jazz. Ak ste chytrí, môžete skutočne vypočítať pole Offset za chodu z originálu, ale je to o niečo menej jasné.

Možno príliš neskoro na odpoveď, ale našiel som tento kúsok kódu niekde v mojej mysli, keď som sa pokúšal získať náhodné údaje z databázy na základe náhodného ID s výnimkou nejakého čísla.

$excludedData = pole(); // Toto je vaše vylúčené číslo $maxVal = $this->db->count_all_results("game_pertanyaan"); // Získanie maximálneho počtu na základe mojej databázy $randomNum = rand(1, $maxVal); // Urobte prvé spustenie, myslím, že to môžete vložiť priamo do parametra while > in_array, zdá sa, že tiež funguje, je to na vás, zatiaľ čo (in_array($randomNum, $excludedData)) ( $randomNum = rand(1, $maxVal); ) $randomNum; //Vaše náhodné číslo s výnimkou čísla, ktoré si vyberiete

Náhodné čísla sú neoddeliteľnou súčasťou programovania, najmä pokiaľ ide o bezpečnostné systémy. Napríklad kryptografia sa spolieha na generovanie náhodných hodnôt na vytváranie čísel, ktoré nemožno predpovedať. Samozrejme, v PHP hrajú náhodné čísla obrovskú úlohu: pomocou nich môžeme generovať tokeny, soľ a ďalšie hodnoty.

Generovanie náhodných čísel je založené na špeciálnych algoritmoch. Vstupným parametrom, od ktorého sa algoritmus spustí, môže byť náhodná hodnota alebo vopred určená hodnota.

V tomto článku budeme hovoriť o náhodných číslach: ako sa generujú a kde sa dajú použiť.

Použitie náhodných čísel

Náhodné čísla hrajú v PHP obrovskú úlohu, pretože veľmi často používané na rôzne účely. V zásade súvisia s bezpečnosťou. Na ich základe sa generujú tokeny CSRF, kľúče API, hodnoty pre autentifikáciu, hodnoty pre resetovanie hesiel a oveľa viac. Toto všetko sa robí preto, aby sa výsledná hodnota nedala predpovedať.

Najdôležitejšie príklady použitia náhodných hodnôt sú:

  • Generovanie soli pre kryptografiu- náhodné číslo soli sa spravidla používa na jednosmerné šifrovanie, ako aj na hashovanie hesiel. Táto náhodná hodnota sa používa ako inicializačný vektor v kryptografii.
  • Generovanie náhodných hodnôt, ako je ID relácie- PHP sa používa na vytváranie obrovského množstva aplikácií, kde je bezpečnosť na prvom mieste. Mnohé funkcie sú založené na práci s reláciami a vygenerovanými ID relácií.
  • Generovanie autentifikačných tokenov, ktoré je takmer nemožné predvídať- mnohé PHP aplikácie sú založené na spolupráci s inými systémami cez špeciálne API rozhrania. Zvyčajne pred použitím API musíte prejsť procesom autentifikácie. Získanie ťažko uhádnuteľných hodnôt pre tokeny je veľmi ťažké. Preto sa v týchto úlohách používajú náhodné čísla.

Generátory náhodných čísel

Náhodné čísla používané vo vyššie opísaných prípadoch sú v PHP generované pseudogenerátormi. K dispozícii je niekoľko algoritmov:

    Lineárna kongruentná metóda pri použití funkcie lcg_value().

    Mersennov vír, ktorý používa funkcia mt_rand().

    Funkcia rand(), ktorá používa podobnú funkciu v jazyku C.

V skutočnosti tieto funkcie nevracajú náhodné čísla, ale čísla distribuované takým spôsobom, že vyzerajú ako náhodné. Poradie týchto čísel závisí od základného náhodného čísla v rámci implementovaného algoritmu.

Základné čísla pre generátory

Základné čísla alebo vektory takýchto čísel sú súbory údajov, ktoré sa používajú na generovanie náhodných čísel. Generátory pseudonáhodných čísel fungujú len na ich základe. Ak útočník pozná toto základné číslo, potom bude v budúcnosti schopný predpovedať hodnoty vašich náhodných čísel.

V PHP môžete nastaviť základné čísla dvoma spôsobmi. Prvým je použitie funkcie mt_srand(). Táto metóda sa používa hlavne pri jednotkových testoch náhodnej série. Druhý spôsob je nechať PHP generovať základné čísla samo. Od verzie 4.2 túto možnosť poskytuje PHP. Následne bude Mersennov Vortex použitý na generovanie náhodných čísel.

PHP generuje základné číslo v závislosti od operačného systému. Na platformách Linux môžete použiť funkcie mcrypt_create_iv() alebo openssl_pseudo_random_bytes() v /dev/urandom. Windows poskytuje špeciálny pseudogenerátor, ku ktorému je možné pristupovať prostredníctvom funkcií openssl_pseudo_random_bytes() a mcrypt_create_iv().

Výsledok

Keďže náhodné čísla hrajú obrovskú úlohu pri vytváraní bezpečných webových aplikácií, musíme vedieť viac o tom, ako fungujú. Ak chcete sami generovať základné čísla pre pseudogenerátory, uistite sa, že sú vaše metódy spoľahlivé.