C++
Slumpmässig nummergenerering
Sök…
Anmärkningar
Slumpmässig nummergenerering i C ++ tillhandahålls av <random>
-huvudet. Denna rubrik definierar slumpmässiga enheter, pseudo-slumpmässiga generatorer och distributioner.
Slumpmässiga enheter returnerar slumpmässiga nummer som tillhandahålls av operativsystemet. De bör antingen användas för initialisering av pseudo-slumpmässiga generatorer eller direkt för kryptografiska ändamål.
Pseudo-slumpmässiga generatorer returnerar heltal pseudo-slumpmässiga nummer baserat på deras ursprungliga utsäde. Det pseudo-slumpmässiga talområdet spänner vanligtvis över alla värden av en osignerad typ. Alla pseudo-slumpmässiga generatorer i standardbiblioteket kommer att returnera samma nummer för samma initiala frö för alla plattformar.
Distributioner konsumerar slumpmässiga nummer från pseudo-slumpmässiga generatorer eller slumpmässiga enheter och producerar slumpmässiga nummer med nödvändig distribution. Distributioner är inte plattformsoberoende och kan producera olika nummer för samma generatorer med samma initiala frön på olika plattformar.
Äkta slumpmässigt värde generator
För att generera riktiga slumpmässiga värden som kan användas för kryptografi std::random_device
användas som generator.
#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
används på samma sätt som en pseudo-slumpmässig värdegenerator används.
std::random_device
kan emellertid implementeras i termer av en implementeringsdefinerad pseudo-random number-motor om en icke-deterministisk källa (t.ex. en hårdvara) inte är tillgänglig för implementeringen.
Detektering av sådana implementeringar bör vara möjligt via entropy
(som returnerar noll när generatorn är helt deterministisk), men många populära bibliotek (både GCC: s libstdc ++ och LLVM: s libc ++) returnerar alltid noll, även när de använder extern slumpmässighet av hög kvalitet. .
Genererar ett pseudo-slumpmässigt nummer
En pseudo-slumptalsgenerator genererar värden som kan gissas baserat på tidigare genererade värden. Med andra ord: det är deterministiskt. Använd inte en pseudo-slumptalsgenerator i situationer där ett riktigt slumpmässigt nummer krävs.
#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;
}
Denna kod skapar en slumptalsgenerator och en fördelning som genererar heltal i intervallet [0,9] med lika stor sannolikhet. Det räknar sedan hur många gånger varje resultat genererades.
Mallparametern för std::uniform_int_distribution<T>
anger vilken typ av heltal som ska genereras. Använd std::uniform_real_distribution<T>
att generera flottörer eller fördubblingar.
Använda generatoren för flera distributioner
Slumptalsgeneratorn kan (och borde) användas för flera distributioner.
#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;
}
I detta exempel definieras endast en generator. Därefter används det för att generera ett slumpmässigt värde i tre olika distributioner. Den rigged_dice
fördelningen kommer att generera ett värde mellan 0 och 5, men genererar nästan alltid en 5
, eftersom chansen att generera en 5
är 100 / 105
.