cpp-utilities/misc/random.cpp

126 lines
4.2 KiB
C++
Raw Normal View History

2015-09-06 20:19:09 +02:00
#include "./random.h"
2015-04-22 18:36:40 +02:00
#include <iomanip>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
using namespace std;
/*!
* \namespace MiscUtilities
* \brief Contains miscellaneous utility functions.
*/
2016-01-27 02:17:06 +01:00
namespace RandomUtilities {
2015-04-22 18:36:40 +02:00
//! @cond
const char letters[28] = "qwertzuiopasdfghjklyxcvbnm";
const char capitalLetters[28] = "QWERTZUIOPASDFGHJKLYXCVBNM";
const char numbers[11] = "1234567890";
const char symbols[24] = "!\"$%&/()=?'#*+~-_><.:,;";
//! @endcond
/*!
2016-01-18 23:41:30 +01:00
* \brief Generates a random character sequence using the given \a randomizer.
2016-01-27 02:17:06 +01:00
* \remarks Might be removed because not used anymore.
2015-04-22 18:36:40 +02:00
*/
2015-10-06 22:28:33 +02:00
void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int ()> randomizer, int highestRandomNumber, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
2015-04-22 18:36:40 +02:00
{
2015-10-06 22:28:33 +02:00
if(length) {
2015-04-22 18:36:40 +02:00
return;
}
2015-10-06 22:28:33 +02:00
signed char categoryCount = 0;
2015-04-22 18:36:40 +02:00
bool needSmallLetter = false;
bool needCapitalLetter = false;
bool needNumber = false;
bool needSymbol = false;
if(useSmallLetters) {
needSmallLetter = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useCapitalLetters) {
needCapitalLetter = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useNumbers) {
needNumber = useAtLeastOneOfEachCategory;
++categoryCount;
}
if(useSymbols) {
needSymbol = useAtLeastOneOfEachCategory;
++categoryCount;
}
2015-10-06 22:28:33 +02:00
signed char neededCharacters = useAtLeastOneOfEachCategory ? categoryCount : 0;
if(!categoryCount) {
*result = '\0';
2015-04-22 18:36:40 +02:00
return;
}
2015-10-06 22:28:33 +02:00
for(char *i = result, *end = result + length; i < end; ++i) {
2015-04-22 18:36:40 +02:00
int category = -1;
2015-10-06 22:28:33 +02:00
if((neededCharacters > 0 && (randomizer() < (highestRandomNumber / 2.0))) || ((end - i) >= neededCharacters)) {
2015-04-22 18:36:40 +02:00
if(needSmallLetter)
category = 0;
if(needCapitalLetter && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1;
if(needNumber && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2;
if(needSymbol && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3;
} else {
if(useSmallLetters)
category = 0;
if(useCapitalLetters && ((category == -1) || (randomizer() < (highestRandomNumber / 2.0))))
category = 1;
if(useNumbers && ((category == -1) || (randomizer() < (highestRandomNumber / 4.0))))
category = 2;
if(useSymbols && ((category == -1) || (randomizer() < (highestRandomNumber / 8.0))))
category = 3;
}
switch(category) {
case 0:
2015-10-06 22:28:33 +02:00
*i = letters[rand() % 26];
2015-04-22 18:36:40 +02:00
if(needSmallLetter) {
needSmallLetter = false;
--neededCharacters;
}
break;
case 1:
2015-10-06 22:28:33 +02:00
*i = capitalLetters[rand() % 26];
2015-04-22 18:36:40 +02:00
if(needCapitalLetter) {
needCapitalLetter = false;
--neededCharacters;
}
break;
case 2:
2015-10-06 22:28:33 +02:00
*i = numbers[rand() % 9];
2015-04-22 18:36:40 +02:00
if(needNumber) {
needNumber = false;
--neededCharacters;
}
break;
case 3:
2015-10-06 22:28:33 +02:00
*i = symbols[rand() % 22];
2015-04-22 18:36:40 +02:00
if(needSymbol) {
needSymbol = false;
--neededCharacters;
}
break;
}
}
}
/*!
2016-01-18 23:41:30 +01:00
* \brief Generates a random character sequence using std::rand().
2016-01-27 02:17:06 +01:00
* \remarks Might be removed because not used anymore.
2015-04-22 18:36:40 +02:00
*/
2015-10-06 22:28:33 +02:00
void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
2015-04-22 18:36:40 +02:00
{
generateRandomCharacterSequence(result, length, rand, RAND_MAX, useSmallLetters, useCapitalLetters, useNumbers, useSymbols, useAtLeastOneOfEachCategory);
}
}