C++
Willekeurige nummer generatie
Zoeken…
Opmerkingen
Het genereren van willekeurige getallen in C ++ wordt verzorgd door de kop <random>
. Deze header definieert willekeurige apparaten, pseudo-willekeurige generatoren en distributies.
Willekeurige apparaten retourneren willekeurige nummers die door het besturingssysteem worden verstrekt. Ze moeten worden gebruikt voor het initialiseren van pseudo-willekeurige generatoren of rechtstreeks voor cryptografische doeleinden.
Pseudo-willekeurige generatoren retourneren gehele pseudo-willekeurige getallen op basis van hun initiële seed. Het pseudo-willekeurige nummerbereik omvat doorgaans alle waarden van een niet-ondertekend type. Alle pseudo-willekeurige generatoren in de standaardbibliotheek retourneren dezelfde nummers voor hetzelfde initiële seed voor alle platforms.
Verdelingen verbruiken willekeurige getallen van pseudo-willekeurige generatoren of willekeurige apparaten en produceren willekeurige getallen met de nodige verdeling. Distributies zijn niet platformonafhankelijk en kunnen verschillende nummers produceren voor dezelfde generators met dezelfde initiële seeds op verschillende platforms.
Echte willekeurige waarde generator
Om echte willekeurige waarden te genereren die kunnen worden gebruikt voor cryptografie, moet std::random_device
als generator worden gebruikt.
#include <iostream>
#include <random>
int main()
{
std::random_device crypto_random_generator;
std::uniform_int_distribution<int> int_distribution(0,9);
int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10000; i++) {
int result = int_distribution(crypto_random_generator);
actual_distribution[result]++;
}
for(int i = 0; i < 10; i++) {
std::cout << actual_distribution[i] << " ";
}
return 0;
}
std::random_device
wordt op dezelfde manier gebruikt als een pseudo-generator voor willekeurige waarden.
std::random_device
kan echter worden geïmplementeerd in termen van een door de implementatie gedefinieerde pseudo-random number engine als een niet-deterministische bron (bijvoorbeeld een hardwareapparaat) niet beschikbaar is voor de implementatie.
Het detecteren van dergelijke implementaties moet mogelijk zijn via de entropy
(die nul retourneert wanneer de generator volledig deterministisch is), maar veel populaire bibliotheken (beide GCC's libstdc ++ en LLVM's libc ++) retourneren altijd nul, zelfs wanneer ze externe willekeurigheid van hoge kwaliteit gebruiken .
Een pseudo-willekeurig getal genereren
Een pseudo-willekeurige nummergenerator genereert waarden die kunnen worden geraden op basis van eerder gegenereerde waarden. Met andere woorden: het is deterministisch. Gebruik geen pseudo-willekeurige nummergenerator in situaties waarin een echt willekeurig nummer is vereist.
#include <iostream>
#include <random>
int main()
{
std::default_random_engine pseudo_random_generator;
std::uniform_int_distribution<int> int_distribution(0, 9);
int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10000; i++) {
int result = int_distribution(pseudo_random_generator);
actual_distribution[result]++;
}
for(int i = 0; i <= 9; i++) {
std::cout << actual_distribution[i] << " ";
}
return 0;
}
Deze code maakt een willekeurige getallengenerator en een verdeling die gehele getallen in het bereik [0,9] genereert met dezelfde waarschijnlijkheid. Vervolgens wordt geteld hoe vaak elk resultaat is gegenereerd.
De sjabloonparameter van std::uniform_int_distribution<T>
geeft het type geheel getal aan dat moet worden gegenereerd. Gebruik std::uniform_real_distribution<T>
om floats of doubles te genereren.
De generator gebruiken voor meerdere distributies
De random number generator kan (en moet) worden gebruikt voor meerdere distributies.
#include <iostream>
#include <random>
int main()
{
std::default_random_engine pseudo_random_generator;
std::uniform_int_distribution<int> int_distribution(0, 9);
std::uniform_real_distribution<float> float_distribution(0.0, 1.0);
std::discrete_distribution<int> rigged_dice({1,1,1,1,1,100});
std::cout << int_distribution(pseudo_random_generator) << std::endl;
std::cout << float_distribution(pseudo_random_generator) << std::endl;
std::cout << (rigged_dice(pseudo_random_generator) + 1) << std::endl;
return 0;
}
In dit voorbeeld is slechts één generator gedefinieerd. Het wordt vervolgens gebruikt om een willekeurige waarde in drie verschillende distributies te genereren. De rigged_dice
verdeling zal een waarde tussen 0 en 5 te genereren, maar genereert bijna altijd een 5
, omdat de kans op het genereren van een 5
is 100 / 105
.