From 60ec25e10bd4a4814231ab0e6510cb153f74adb8 Mon Sep 17 00:00:00 2001 From: hama Date: Thu, 8 Oct 2015 00:37:19 +0200 Subject: [PATCH] ReRandomizer: more generators --- base/ReRandomizer.cpp | 381 +++++++++++++++++++++++++++++++++------ base/ReRandomizer.hpp | 150 ++++++++++++--- cunit/allTests.cpp | 5 +- cunit/cuReRandomizer.cpp | 79 ++++++++ cunit/cunit.pro | 1 + os/ReFileSystem.cpp | 4 +- 6 files changed, 530 insertions(+), 90 deletions(-) create mode 100644 cunit/cuReRandomizer.cpp diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index 9c5b69f..6b4fa8a 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -12,10 +12,25 @@ #include "base/rebase.hpp" static bool s_trace = false; +const int ReRandomizer::m_primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, + 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, + 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, + 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, + 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, + 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, + 659, 661, 673, 677, 683, 691 }; +const int ReRandomizer::m_countPrimes = sizeof ReRandomizer::m_primes + / sizeof(int); + /** * @brief Constructor. + * + * @param name the name of the generator */ -ReRandomizer::ReRandomizer() { +ReRandomizer::ReRandomizer(const char* name) : + m_name(name) { } /** * @brief Destructor. @@ -28,16 +43,14 @@ inline int abs(int x) { return x < 0 ? -x : x; } #endif + /** - * @brief Returns the next random character. - * - * The character is in the range ' ' .. chr(127) (inclusive). + * Returns the name of the generator. * - * @return The next random character. + * @return the name */ -char ReRandomizer::nextChar() { - char rc = nextInt(' ', ' ' + CHARRANGE - 1); - return rc; +const QByteArray& ReRandomizer::name() const { + return m_name; } /** @@ -63,6 +76,19 @@ ReRandomizer::seed_t ReRandomizer::nearTrueRandom() { #endif return rc; } + +/** + * @brief Returns the next random character. + * + * The character is in the range ' ' .. chr(127) (inclusive). + * + * @return The next random character. + */ +char ReRandomizer::nextChar() { + char rc = nextInt(' ', ' ' + CHARRANGE - 1); + return rc; +} + /** * @brief Returns the next random integer. * @@ -218,36 +244,135 @@ void ReRandomizer::shuffle(void* array, size_t length, size_t elemSize) { } } /** - * @brief Constructor. + * Builds a number from a text by hasing. + * + * Conditions: + * + * + * @param text the text to hash + * @return a number */ -ReCongruentialGenerator::ReCongruentialGenerator() : - m_seed(0x4711), - m_factor(214013), - m_increment(2531011), - m_lastSetSeed(0x4711) { +ReRandomizer::seed_t ReRandomizer::hash(const QByteArray& text) { + seed_t rc = 0x200a110b190c580dLL; + int ixPrimes = m_countPrimes / 2; + for (int ix = text.length() - 1; ix >= 0; ix--) { + rc = rc * m_primes[ixPrimes] + text.at(ix) * m_primes[ixPrimes - 1]; + if ((ixPrimes -= 2) <= 0) + ixPrimes = m_countPrimes; + } + return rc; } + /** - * @brief Destructor. + * Converts a text into a seed + * @param text + * @param seed */ -ReCongruentialGenerator::~ReCongruentialGenerator() { +void ReRandomizer::hash(const QByteArray& text, QByteArray& seed) { + int ixSrc = text.length() / sizeof(seed_t) - 1; + int maxSrc = text.length() / sizeof(seed_t) - 1; + const seed_t* src = reinterpret_cast(text.constData()); + seed_t srcSeed = 0x44112200773355LL; + if (text.length() < (int) sizeof(seed_t)) { + for (int ix = text.length() - 1; ix >= 0; ix--) + srcSeed = (srcSeed << 8) | text.at(ix); + src = &srcSeed; + maxSrc = 1; + } + seed_t last = 0x112012041919891LL; + seed_t* trg = reinterpret_cast(seed.data()); + int ixTrg; + int ixPrime = m_countPrimes; + int maxTrg = seed.length() / sizeof(seed_t) - 1; + for (ixTrg = 0; ixTrg < maxTrg; ixTrg++) { + last = trg[ixTrg] = last * m_primes[ixPrime] + + src[ixSrc] * m_primes[ixPrime - 1]; + if ((ixPrime -= 2) <= 0) + ixPrime = m_countPrimes; + if (--ixSrc <= 0) + ixSrc = maxSrc; + } + ixSrc = text.length() - 1; + char* trgPtr = reinterpret_cast(seed.data()); + for (ixTrg = seed.length() % sizeof(seed_t); ixTrg < seed.length(); + ixTrg++) { + last = last + text.at(ixSrc) * m_primes[ixPrime]; + trgPtr[ixTrg] = (char) last; + if (--ixPrime < 0) + ixPrime = m_countPrimes; + if (--ixSrc < 0) + ixSrc = text.length() - 1; + } + ixTrg = 0; + for (int ix = seed.length(); ix < text.length(); ix++) { + trg[ixTrg] ^= text.at(ixSrc); + if (--ixSrc < 0) + ixSrc = text.length() - 1; + if (ixTrg++ >= seed.length()) + ixTrg = 0; + } } /** - * @brief Returns the current factor. + * @brief Sets the seed to the value given by the last setSeed(). * - * @return The current factor. + * Note: The constructor does the first setSeed(). */ -ReRandomizer::seed_t ReCongruentialGenerator::factor() const { - return m_factor; +/** + * Constructor. + * + * @param name the name of the generator + */ +ReSingleSeedRandomizer::ReSingleSeedRandomizer(const char* name) : + ReRandomizer(name), + m_seed(0x1120120419198991ull), + m_lastSetSeed(0x1120120419198991ull) { +} +/** + * Sets the seed to the start point (defined with setSeed()). + */ +void ReSingleSeedRandomizer::reset() { + m_seed = m_lastSetSeed; } /** - * @brief Returns the current increment. + * Sets the current point of pseudo random. * - * @return The current increment. + * @param seed the current point of pseudo random */ -ReRandomizer::seed_t ReCongruentialGenerator::increment() const { - return m_increment; +void ReSingleSeedRandomizer::restoreSeed(const QByteArray& seed) { + if (seed.size() >= (int) sizeof(seed_t)) { + memcpy(&m_seed, seed.constData(), sizeof m_seed); + } else { + QByteArray buffer = seed; + buffer.resize(sizeof m_seed); + memset(buffer.data() + seed.size(), 0, sizeof(m_seed) - seed.size()); + memcpy(&m_seed, buffer.constData(), sizeof m_seed); + } + m_lastSetSeed = m_seed; +} + +/** @brief Sets the current seed. + * + * @param seed The seed to set. + */ +void ReSingleSeedRandomizer::setSeed(seed_t seed) { + m_seed = m_lastSetSeed = seed; + if (s_trace) + printf(" Seed: %llx ", (long long) seed); +} + +/** + * Gets the current point of pseudo random. + * + * @param seed the current point of pseudo random + */ +void ReSingleSeedRandomizer::saveSeed(QByteArray& seed) const { + seed.resize(sizeof m_seed); + memcpy(seed.data(), &m_seed, sizeof m_seed); } /** @@ -255,17 +380,43 @@ ReRandomizer::seed_t ReCongruentialGenerator::increment() const { * * @return The current seed. */ -ReRandomizer::seed_t ReCongruentialGenerator::seed() const { +ReRandomizer::seed_t ReSingleSeedRandomizer::seed() const { return m_seed; } /** - * @brief Sets the seed to the value given by the last setSeed(). + * Converts a text (e.g. password) into the generator specific seed. * - * Note: The constructor does the first setSeed(). + * @param text the text to convert */ -void ReCongruentialGenerator::reset() { - m_seed = m_lastSetSeed; +void ReSingleSeedRandomizer::textToSeed(const QByteArray& text) { + setSeed(hash(text)); +} + +/** + * @brief Constructor. + */ +ReCongruentialGeneratorBase::ReCongruentialGeneratorBase() : + m_factor(214013), + m_increment(2531011) { +} + +/** + * @brief Returns the current factor. + * + * @return The current factor. + */ +ReRandomizer::seed_t ReCongruentialGeneratorBase::factor() const { + return m_factor; +} + +/** + * @brief Returns the current increment. + * + * @return The current increment. + */ +ReRandomizer::seed_t ReCongruentialGeneratorBase::increment() const { + return m_increment; } /** @@ -273,7 +424,7 @@ void ReCongruentialGenerator::reset() { * * @param factor The new factor. */ -void ReCongruentialGenerator::setFactor(seed_t factor) { +void ReCongruentialGeneratorBase::setFactor(ReRandomizer::seed_t factor) { this->m_factor = factor; } @@ -282,58 +433,170 @@ void ReCongruentialGenerator::setFactor(seed_t factor) { * * @param increment The new increment. */ -void ReCongruentialGenerator::setIncrement(seed_t increment) { +void ReCongruentialGeneratorBase::setIncrement(ReRandomizer::seed_t increment) { this->m_increment = increment; } -/** @brief Sets the current seed. +/** + * @brief Constructor. + */ +ReCongruentialGenerator::ReCongruentialGenerator() : + ReSingleSeedRandomizer("Linear Congruential Generator"), + ReCongruentialGeneratorBase() { +} + +/** @brief Returns the next 64 bit pseudo random number. * - * @param seed The seed to set. + * A congruential generator produces good random in the most significant + * bits. Therefore we exchange the bits of the result. + * Then x % m returns better results. + * + * @return a pseudo random number */ -void ReCongruentialGenerator::setSeed(seed_t seed) { - m_seed = m_lastSetSeed = seed; - if (s_trace) - printf(" Seed: %llx ", (long long) seed); +ReRandomizer::seed_t ReRotateRandomizer::nextSeed() { + seed_t rc = ReCongruentialGenerator::nextSeed(); + rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffll); + return rc; } /** - * Gets the current point of pseudo random. + * Constructor. + */ + +ReMultiSeedRandomizer::ReMultiSeedRandomizer(int countSeeds, const char* name) : + ReRandomizer(name), + m_countSeeds(min(256, max(countSeeds, 2))), + m_seedBuffer(), + m_startSeed(), + m_seeds() { + m_seedBuffer.fill(0x38, m_countSeeds * sizeof m_seeds[0]); + m_seeds = reinterpret_cast(m_seedBuffer.data()); + m_startSeed = m_seedBuffer; +} + +/** @brief Sets the instance to a defined start state. + */ +void ReMultiSeedRandomizer::reset() { + m_seedBuffer = m_startSeed; +} + +/** + * Sets the current point of pseudo random with a seed saved by saveSeed(). * * @param seed the current point of pseudo random */ -void ReCongruentialGenerator::seed(QByteArray& seed) { - seed.resize(sizeof m_seed); - memcpy(seed.data(), &m_seed, sizeof m_seed); +void ReMultiSeedRandomizer::restoreSeed(const QByteArray& seed) { + size_t length = min(seed.length(), m_seedBuffer.length()); + memcpy(m_seedBuffer.data(), seed.constData(), length); } /** - * Sets the current point of pseudo random. + * Stores the the current point of pseudo random in a buffer. + * + * Restoring is done by restoreSeed() * * @param seed the current point of pseudo random */ -void ReCongruentialGenerator::setSeed(const QByteArray& seed) { - if (seed.size() >= sizeof(seed_t)) { - memcpy(&m_seed, seed.constData(), sizeof m_seed); - } else { - QByteArray buffer = seed; - buffer.resize(sizeof m_seed); - memset(buffer.data() + seed.size(), 0, sizeof(m_seed) - seed.size()); - memcpy(&m_seed, buffer.constData(), sizeof m_seed); - } - m_lastSetSeed = m_seed; +void ReMultiSeedRandomizer::saveSeed(QByteArray& seed) const { + size_t size = m_seedBuffer.length(); + seed.resize(size); + memcpy(seed.data(), m_seedBuffer.constData(), size); +} +/** + * Converts a text (e.g. password) into the generator specific seed. + * + * @param text the text to convert + */ +void ReMultiSeedRandomizer::textToSeed(const QByteArray& text) { + hash(text, m_seedBuffer); + m_startSeed = m_seedBuffer; } -/** @brief Returns the next 64 bit pseudo random number. +/** + * Constructor. * - * A congruential generator produces good random in the most significant - * bits. Therefore we exchange the bits of the result. - * Then x % m returns better results. + * @param countSeeds number of seeds + */ +ReMultiCongruentialGenerator::ReMultiCongruentialGenerator(int countSeeds) : + ReMultiSeedRandomizer(countSeeds, "Multi LCG"), + ReCongruentialGeneratorBase(), + m_currentSeed(-1) { +} + +/** @brief Returns the next 64 bit pseudo random number. * * @return a pseudo random number */ -ReRandomizer::seed_t ReShiftRandom::nextSeed() { - seed_t rc = ReCongruentialGenerator::nextSeed(); - rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffll); +ReRandomizer::seed_t ReMultiCongruentialGenerator::nextSeed() { + m_currentSeed = (m_currentSeed + 1) % m_countSeeds; + seed_t rc = m_seeds[m_currentSeed] * m_factor + m_increment; + m_seeds[m_currentSeed] = rc; + rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffLL); return rc; } + +/** + * Constructor. + * + * @return + */ +ReXorShift64Randomizer::ReXorShift64Randomizer() : + ReSingleSeedRandomizer("ShiftXor64") { +} + +/** + * Calculates the next pseudo random value. + * + * @return the next pseudo random value + */ +ReRandomizer::seed_t ReXorShift64Randomizer::nextSeed() { + m_seed ^= m_seed << 13; + m_seed ^= m_seed >> 7; + m_seed ^= m_seed << 17; + return m_seed; +} + +/** + * Constructor. + */ +ReKISSRandomizer::ReKISSRandomizer() : + ReMultiSeedRandomizer(6, "KISS") { + m_seeds[0] = 1234567890987654321ULL; + m_seeds[1] = 362436362436362436ULL; + m_seeds[2] = 1066149217761810ULL; + m_seeds[3] = 123456123456123456ULL; + m_seeds[4] = 0x20ab110c19d058ULL; + m_seeds[5] = 0x20ab040c19d091ULL; +} + +/** + * Calculates the next pseudo random value. + * @return + */ +ReRandomizer::seed_t ReKISSRandomizer::nextSeed() { + static const int x = 0; + static const int y = 1; + static const int z = 2; + static const int c = 3; + static const int fac = 4; + static const int inc = 5; + + seed_t t; + + // Linear congruence generator + m_seeds[z] = m_seeds[fac] * m_seeds[z] + m_seeds[inc]; + + // Xorshift + m_seeds[y] ^= (m_seeds[y] << 13); + m_seeds[y] ^= (m_seeds[y] >> 17); + m_seeds[y] ^= (m_seeds[y] << 43); + + // Multiply-with-carry + t = (m_seeds[x] << 58) + m_seeds[c]; + m_seeds[c] = (m_seeds[x] >> 6); + m_seeds[x] += t; + m_seeds[c] += (m_seeds[x] < t); + + return m_seeds[x] + m_seeds[y] + m_seeds[z]; +} diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index 6e24fa7..2a1255f 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -23,71 +23,165 @@ public: }; typedef uint64_t seed_t; public: - ReRandomizer(); + ReRandomizer(const char* name); virtual ~ReRandomizer(); public: - virtual int nextInt(int maxValue = INT_MAX, int minValue = 0); - virtual int64_t nextInt64(int64_t maxValue = LLONG_MAX, - int64_t minValue = 0); + const QByteArray& name() const; + seed_t nearTrueRandom(); char nextChar(); + int nextInt(int maxValue = INT_MAX, int minValue = 0); + int64_t nextInt64(int64_t maxValue = LLONG_MAX, int64_t minValue = 0); const char* nextString(int minLength, int maxLength, QByteArray& buffer); void shuffle(void* array, size_t length, size_t elemSize); +public: /** @brief Sets the instance to a defined start state. */ virtual void reset() = 0; /** - * Gets the current point of pseudo random. + * Sets the current point of pseudo random with a seed saved by saveSeed(). * * @param seed the current point of pseudo random */ - virtual void seed(QByteArray& seed) = 0; + virtual void restoreSeed(const QByteArray& seed) = 0; /** - * Sets the current point of pseudo random. + * Stores the the current point of pseudo random in a buffer. + * + * Restoring is done by restoreSeed() * * @param seed the current point of pseudo random */ - virtual void setSeed(QByteArray& seed) = 0; + virtual void saveSeed(QByteArray& seed) const = 0; + /** + * Converts a text (e.g. password) into the generator specific seed. + * @param text the text to convert + */ + virtual void textToSeed(const QByteArray& text) = 0; +public: + static seed_t hash(const QByteArray& text); + static void hash(const QByteArray& text, QByteArray& seed); + protected: /** @brief Returns the next pseudo random number. * @return the next pseudo random number * */ virtual seed_t nextSeed() = 0; +protected: + QByteArray m_name; public: - seed_t nearTrueRandom(); + // the first 125 prime numbers + static const int m_primes[]; + static const int m_countPrimes; }; /** - * Implements a simple random generator. - * A linear congruential generator produces the next value using this formula: - * seed = (seed * factor + increment) % modulus - * In this implementation modulus is 2**64. + * Base class for pseudo random generators with a state variable (seed) of 64 bit. */ -class ReCongruentialGenerator: public ReRandomizer { +class ReSingleSeedRandomizer: public ReRandomizer { public: - ReCongruentialGenerator(); - virtual ~ReCongruentialGenerator(); + ReSingleSeedRandomizer(const char* name); public: - seed_t factor() const; - seed_t increment() const; virtual void reset(); seed_t seed() const; - virtual void seed(QByteArray& seed); - void setFactor(seed_t factor); - void setIncrement(seed_t increment); void setSeed(seed_t m_seed); - virtual void setSeed(const QByteArray& seed); + virtual void restoreSeed(const QByteArray& seed); + virtual void saveSeed(QByteArray& seed) const; + virtual void textToSeed(const QByteArray& text); protected: - friend class ReShiftRandom; - virtual seed_t nextSeed(); -private: seed_t m_seed; - seed_t m_factor; - seed_t m_increment; seed_t m_lastSetSeed; }; -class ReShiftRandom: public ReCongruentialGenerator { +class ReCongruentialGeneratorBase { +public: + ReCongruentialGeneratorBase(); +public: + ReRandomizer::seed_t factor() const; + ReRandomizer::seed_t increment() const; + void setFactor(ReRandomizer::seed_t factor); + void setIncrement(ReRandomizer::seed_t increment); +protected: + ReRandomizer::seed_t m_factor; + ReRandomizer::seed_t m_increment; +}; + +/** + * Implements a simple pseudo random generator. + * A linear congruential generator produces the next value using this formula: + * seed = (seed * factor + increment) % modulus + * In this implementation modulus is 2**64. + */ +class ReCongruentialGenerator: public ReSingleSeedRandomizer, + public ReCongruentialGeneratorBase { +public: + ReCongruentialGenerator(); +protected: + friend class ReShiftRandom; + virtual seed_t nextSeed(); +}; + +/** + * A simple pseudo random generator simular to ReCongruentialGenerator. + * + * A congruential generator produces good random in the most significant + * bits. Therefore we exchange the bits of the result. + * Then x % m returns better results. + */ +class ReRotateRandomizer: public ReCongruentialGenerator { +protected: + virtual seed_t nextSeed(); +}; + +/** + * Abstract base class for pseudo random generators with a state variable larger than 64 bit. + */ +class ReMultiSeedRandomizer: public ReRandomizer { +public: + ReMultiSeedRandomizer(int countSeeds, const char* name); +public: + virtual void reset(); + virtual void restoreSeed(const QByteArray& seed); + virtual void saveSeed(QByteArray& seed) const; + virtual void textToSeed(const QByteArray& text); protected: + int m_countSeeds; + QByteArray m_seedBuffer; + QByteArray m_startSeed; + seed_t* m_seeds; +}; + +/** + * A simple pseudo random generator simular to ReCongruentialGenerator. + * + * Difference: An array of seeds is used (round robin). + */ +class ReMultiCongruentialGenerator: public ReMultiSeedRandomizer, + public ReCongruentialGeneratorBase { +public: + ReMultiCongruentialGenerator(int countSeeds); +public: + virtual seed_t nextSeed(); +protected: + int m_currentSeed; +}; + +class ReXorShift64Randomizer: public ReSingleSeedRandomizer { +public: + ReXorShift64Randomizer(); +public: + virtual seed_t nextSeed(); +}; + +/** + * A simple pseudo random generator but it fulfills some statistically tests. + * + * Combines a congruent generator, a xor-shift generator and the multiply + * with carry method. + */ +class ReKISSRandomizer: public ReMultiSeedRandomizer { +public: + ReKISSRandomizer(); +public: virtual seed_t nextSeed(); }; + #endif /* RANDOMIZER_H_ */ diff --git a/cunit/allTests.cpp b/cunit/allTests.cpp index cad6fc2..4bf3cf0 100644 --- a/cunit/allTests.cpp +++ b/cunit/allTests.cpp @@ -29,6 +29,7 @@ static void testGui() { } static void testBase() { + void testReRandomizer(); void testReByteStorage(); void testReCharPtrMap(); void testReConfig(); @@ -40,11 +41,13 @@ static void testBase() { void testReFile(); void testReFileUtils(); void testReMatcher(); + testReRandomizer(); testReMatcher(); testReQStringUtil(); testReFile(); testReFileUtils(); if (s_allTest) { + testReRandomizer(); testReByteStorage(); testReCharPtrMap(); testReConfig(); @@ -89,8 +92,8 @@ static void testOs() { testReFileSystem(); } void allTests() { - testOs(); testBase(); + testOs(); testGui(); if (s_allTest) { testBase(); diff --git a/cunit/cuReRandomizer.cpp b/cunit/cuReRandomizer.cpp new file mode 100644 index 0000000..879654f --- /dev/null +++ b/cunit/cuReRandomizer.cpp @@ -0,0 +1,79 @@ +/* + * cuReRandomizer.cpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ +/** @file + * @brief Unit test of the ReString tools. + */ + +#include "../base/rebase.hpp" + +class TestReRandomizer: public ReTest { +public: + TestReRandomizer() : + ReTest("ReRandomizer") { + doIt(); + } + +public: + void testOne(ReRandomizer& rand) { + QByteArray password("1"); + QByteArray seed1; + QByteArray seed2; + rand.saveSeed(seed1); + char cc1 = rand.nextChar(); + rand.reset(); + rand.saveSeed(seed2); + checkEqu(seed1, seed2); + + rand.textToSeed(password); + rand.saveSeed(seed1); + char cc2 = rand.nextChar(); + checkEqu(cc1, cc2); + rand.reset(); + rand.saveSeed(seed2); + checkEqu(seed1, seed2); + + int numbers[16]; + for (size_t ix = 0; ix < sizeof numbers / sizeof numbers[0]; ix++) + numbers[ix] = rand.nextInt(); + rand.reset(); + rand.saveSeed(seed2); + checkEqu(seed1, seed2); + for (size_t ix = 0; ix < sizeof numbers / sizeof numbers[0]; ix++) + checkEqu(numbers[ix], rand.nextInt()); + clock_t start = clock(); + for (int ix = 0; ix < 1000 * 1000; ix++) { + rand.nextInt64(); + } + double duration = double(clock() - start) / CLOCKS_PER_SEC; + printf("%s (1E6): %.3f sec\n", rand.name().constData(), duration); + } + + void testBasics() { + ReKISSRandomizer rand3; + testOne(rand3); + ReCongruentialGenerator rand; + testOne(rand); + ReRotateRandomizer rand2; + testOne(rand2); + ReMultiCongruentialGenerator rand4(4); + testOne(rand4); + ReXorShift64Randomizer rand5; + testOne(rand5); + } + + virtual void run(void) { + testBasics(); + } +}; +void testReRandomizer() { + TestReRandomizer test; +} + diff --git a/cunit/cunit.pro b/cunit/cunit.pro index 7f33dea..1a2bb9d 100644 --- a/cunit/cunit.pro +++ b/cunit/cunit.pro @@ -16,6 +16,7 @@ TEMPLATE = app INCLUDEPATH = .. SOURCES += main.cpp \ + cuReRandomizer.cpp \ cuReQStringUtils.cpp \ cuReStringUtils.cpp \ cuReFile.cpp \ diff --git a/os/ReFileSystem.cpp b/os/ReFileSystem.cpp index 842814d..49a4233 100644 --- a/os/ReFileSystem.cpp +++ b/os/ReFileSystem.cpp @@ -619,8 +619,8 @@ ReCryptFileSystem::ReCryptFileSystem(ReFileSystem& hostFileSystem, m_contentSeed(), m_nameSeed(), m_buffer() { - m_contentRandom.seed(m_contentSeed); - m_nameRandom.seed(m_nameSeed); + m_contentRandom.saveSeed(m_contentSeed); + m_nameRandom.saveSeed(m_nameSeed); m_buffer.reserve(256); } -- 2.39.5