From: hama Date: Thu, 8 Oct 2015 23:25:05 +0000 (+0200) Subject: KISS works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=85c8fbddc29c5ad34e40ee1b1e44490fe164bcdf;p=reqt KISS works --- diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index 6b4fa8a..a2afb57 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -471,13 +471,16 @@ ReMultiSeedRandomizer::ReMultiSeedRandomizer(int countSeeds, const char* name) : m_seeds() { m_seedBuffer.fill(0x38, m_countSeeds * sizeof m_seeds[0]); m_seeds = reinterpret_cast(m_seedBuffer.data()); - m_startSeed = m_seedBuffer; + // assignment does not work: copy on write + m_startSeed.resize(m_seedBuffer.length()); + memcpy(m_seedBuffer.data(), m_startSeed.constData(), m_startSeed.length()); } /** @brief Sets the instance to a defined start state. */ void ReMultiSeedRandomizer::reset() { - m_seedBuffer = m_startSeed; + // assignment does not work: copy on write + memcpy(m_seedBuffer.data(), m_startSeed.constData(), m_seedBuffer.length()); } /** @@ -510,7 +513,8 @@ void ReMultiSeedRandomizer::saveSeed(QByteArray& seed) const { */ void ReMultiSeedRandomizer::textToSeed(const QByteArray& text) { hash(text, m_seedBuffer); - m_startSeed = m_seedBuffer; + // assignment does not work: copy on write + memcpy(m_seedBuffer.data(), m_startSeed.constData(), m_seedBuffer.length()); } /** @@ -561,13 +565,28 @@ ReRandomizer::seed_t ReXorShift64Randomizer::nextSeed() { * 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; + ReRandomizer("KISS"), + m_params(), + m_startParams() { + m_params.m_x = 1234567890987654321ULL; + m_params.m_y = 362436362436362436ULL; + m_params.m_z = 1066149217761810ULL; + m_params.m_c = 123456123456123456ULL; + m_startParams = m_params; +} + +/** + * Dumps the state of the generator. + */ +void ReKISSRandomizer::dump() { + printf( + "f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx\n", + m_factor, m_increment, m_params.m_x, m_params.m_x, m_params.m_y, + m_params.m_z); + printf( + "f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx\n", + m_factor, m_increment, m_startParams.m_x, m_startParams.m_x, + m_startParams.m_y, m_startParams.m_z); } /** @@ -575,28 +594,40 @@ ReKISSRandomizer::ReKISSRandomizer() : * @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]; - + m_params.m_z = m_factor * m_params.m_z + m_increment; // Xorshift - m_seeds[y] ^= (m_seeds[y] << 13); - m_seeds[y] ^= (m_seeds[y] >> 17); - m_seeds[y] ^= (m_seeds[y] << 43); + m_params.m_y ^= (m_params.m_y << 13); + m_params.m_y ^= (m_params.m_y >> 17); + m_params.m_y ^= (m_params.m_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); + t = (m_params.m_x << 58) + m_params.m_c; + m_params.m_c = (m_params.m_x >> 6); + m_params.m_x += t; + m_params.m_c += (m_params.m_x < t); + + return m_params.m_x + m_params.m_y + m_params.m_z; +} + +void ReKISSRandomizer::reset() { + m_params = m_startParams; +} + +void ReKISSRandomizer::restoreSeed(const QByteArray& seed) { + restore(seed, m_params); +} + +void ReKISSRandomizer::saveSeed(QByteArray& seed) const { + save(m_params, seed); +} - return m_seeds[x] + m_seeds[y] + m_seeds[z]; +void ReKISSRandomizer::textToSeed(const QByteArray& text) { + QByteArray seeds; + seeds.resize(sizeof m_params); + hash(text, seeds); + restore(seeds, m_params); + m_startParams = m_params; } diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index 2a1255f..fdb4e21 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -34,6 +34,8 @@ public: const char* nextString(int minLength, int maxLength, QByteArray& buffer); void shuffle(void* array, size_t length, size_t elemSize); public: + virtual void dump() { + } /** @brief Sets the instance to a defined start state. */ virtual void reset() = 0; @@ -177,11 +179,45 @@ public: * Combines a congruent generator, a xor-shift generator and the multiply * with carry method. */ -class ReKISSRandomizer: public ReMultiSeedRandomizer { +class ReKISSRandomizer: public ReRandomizer, public ReCongruentialGeneratorBase { +public: + typedef struct { + seed_t m_x; + seed_t m_y; + seed_t m_z; + seed_t m_c; + } params_t; public: ReKISSRandomizer(); public: + virtual void dump(); virtual seed_t nextSeed(); +public: + virtual void reset(); + virtual void restoreSeed(const QByteArray& seed); + virtual void saveSeed(QByteArray& seed) const; + virtual void textToSeed(const QByteArray& text); +private: + /** Stores a parameter set into a buffer. + * @param params parameter set of the KISS generator + * @param buffer OUT: buffer for saving + */ + inline void save(const params_t& params, QByteArray& buffer) const { + buffer.resize(sizeof params); + memcpy(buffer.data(), ¶ms, sizeof params); + } + /** Restores a parameter set from a buffer + * @param buffer the stored parameters + * @param params OUT: the parameter to restore + */ + inline void restore(const QByteArray& buffer, params_t& params) const { + size_t size = min(buffer.length(), sizeof params); + memcpy(¶ms, buffer.constData(), size); + } + +private: + params_t m_params; + params_t m_startParams; }; #endif /* RANDOMIZER_H_ */ diff --git a/cunit/cuReRandomizer.cpp b/cunit/cuReRandomizer.cpp index 879654f..988acf4 100644 --- a/cunit/cuReRandomizer.cpp +++ b/cunit/cuReRandomizer.cpp @@ -34,12 +34,14 @@ public: rand.textToSeed(password); rand.saveSeed(seed1); - char cc2 = rand.nextChar(); - checkEqu(cc1, cc2); + cc1 = rand.nextChar(); rand.reset(); rand.saveSeed(seed2); checkEqu(seed1, seed2); + char cc2 = rand.nextChar(); + checkEqu(cc1, cc2); + rand.reset(); int numbers[16]; for (size_t ix = 0; ix < sizeof numbers / sizeof numbers[0]; ix++) numbers[ix] = rand.nextInt(); @@ -68,8 +70,16 @@ public: ReXorShift64Randomizer rand5; testOne(rand5); } + void special() { + ReKISSRandomizer rand; + int i1 = rand.nextInt(); + rand.reset(); + int i2 = rand.nextInt(); + checkEqu(i1, i2); + } virtual void run(void) { + special(); testBasics(); } };