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());
}
/**
*/
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());
}
/**
* 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);
}
/**
* @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;
}
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;
* 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_ */