#include #include #include #include void debug(DebugLevel level, std::string message) { if (level >= INFO) { std::cerr << DEBUGCHARS[level] << " " << message << std::endl; } } Random::Random() { device.open("/dev/urandom", std::ios::binary); } unsigned int Random::rand() { unsigned int rawnum; int c; for (int i = 0; i < sizeof(int); i++) { c = device.get(); if (c < 0) { debug(CRITICAL, "Read from random source failed"); return 0; } *((unsigned char *) &rawnum + i) = c; } return rawnum; } int Random::random_in_range(int min, int max) { // Range is inclusive, rangesize = count of possible values int rangesize = max - min + 1; unsigned int raw = rand(); // Force random range to be divisable by rangesize // Eg. to get random in range [1,3], rangesize = 3 // If INT_MAX = 7, values are forced to range [0, 5] // Thus, results are [1,2,3,1,2,3], yielding uniform distribution while (raw >= (INT_MAX - INT_MAX % rangesize)) { raw = rand(); } return min + raw % rangesize; }