]> gitweb.hamatoma.de Git - reqt/commitdiff
KISS works
authorhama <hama@siduction.net>
Thu, 8 Oct 2015 23:25:05 +0000 (01:25 +0200)
committerhama <hama@siduction.net>
Thu, 8 Oct 2015 23:25:05 +0000 (01:25 +0200)
base/ReRandomizer.cpp
base/ReRandomizer.hpp
cunit/cuReRandomizer.cpp

index 6b4fa8a1f1f5b120e465e22d8f2e6e1fc8d0513f..a2afb578663d14d215028da698158a5b5ca9b500 100644 (file)
@@ -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<seed_t*>(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;
 }
index 2a1255fdf9f3afe33677e1cded98e4e127428d9b..fdb4e21e5bd66673764cec71392511c27c80ecbc 100644 (file)
@@ -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(), &params, 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(&params, buffer.constData(), size);
+       }
+
+private:
+       params_t m_params;
+       params_t m_startParams;
 };
 
 #endif /* RANDOMIZER_H_ */
index 879654fa2c5752910d1aedc7e3a4c471b47c3fc7..988acf4bc03d7ac260cfae41355b783ad7d503c7 100644 (file)
@@ -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();
        }
 };