]> gitweb.hamatoma.de Git - reqt/commitdiff
Higher prime numbers, MLCG fix
authorhama <hama@siduction.net>
Thu, 22 Oct 2015 22:46:03 +0000 (00:46 +0200)
committerhama <hama@siduction.net>
Thu, 22 Oct 2015 22:46:03 +0000 (00:46 +0200)
* MLCG reads wrong data
* Prime numbers > 2**61

appl/reprime/Prime.cpp
base/ReRandomizer.cpp
base/ReRandomizer.hpp
cunit/cuReRandomizer.cpp

index 6d4637161dcdbd0aed3c40a6cfa4a48496f4283c..781b48d239b9f7800f6d1cb5c6950af19a213356 100644 (file)
@@ -104,7 +104,9 @@ void Prime::storePrimes() {
                }
                if (isPrime) {
                        m_primes[m_countPrimes++] = x;
-                       if (m_countPrimes >= m_maxStoredPrimes || x * x > m_from)
+                       // hex(sqrt(2**63-1)) == 0xb504f333:
+                       if (m_countPrimes >= m_maxStoredPrimes
+                                       || x * x > m_from || x > 0xb504f333)
                                break;
                }
        }
@@ -113,19 +115,19 @@ void Prime::storePrimes() {
 
 void Prime::dump() {
        int64_t last = lastPrime();
-       fprintf(stderr, "count primes: %d size primes: %d last prime: %ld lp*lp: %ld\n",
-                  m_countPrimes, m_sizePrimes, last, last * last);
+       fprintf(stderr, "count/primes: %d/%d last: %lx lp*lp: %lx %.2f%%\n",
+                  m_countPrimes, m_sizePrimes, last, last * last,
+                       (double) last * last * 100.0 / m_from);
 }
 
 void Prime::run(int argc, char* argv[]){
-       int64_t from = 0x82L * 0x10000 * 0x10000 * 10000; //* 0x10000;
+       int64_t from = 0x7fffffffefffefffL;
        int count = 150;
        if (argc > 1){
                int64_t lValue;
                if (sscanf(argv[1], "0x%lx", &lValue) == 1){
-               } else if (sscanf(argv[1], "%ld", &lValue) != 1)
-                       printf("wrong argument 1: %s", argv[1]);
-               else
+                       from = lValue;
+               } else if (sscanf(argv[1], "%ld", &lValue) == 1)
                        from = lValue;
 
                if (argc > 2){
index cda4079813f6b8424dfbcb4cb0c6546cc6c079ea..c1797abc1edacaf2860f4fedfb103ce99348dcd8 100644 (file)
@@ -20,135 +20,135 @@ enum {
 
 const char ReNameScrambler::ESC = '%';
 
-const int64_t ReRandomizer::m_primes[] = {
-       4794328877860651L, // 11086aadb3872b
-       4958110297415603L, // 119d600308dfb3
-       4623102848326049L, // 106cb00308d9a1
-       4891108807597633L, // 1160700308de41
-       4578435188447437L, // 1044100308d8cd
-       5546234485817489L, // 13b445585e4091
-       5389897676242243L, // 132615585e3d43
-       4786884267880873L, // 1101a5585e31a9
-       5241005476646707L, // 129eaaadb38f33
-       4734771998022511L, // 10d2400308db6f
-       5278228526545621L, // 12c085585e3ad5
-       4652881288245079L, // 1087c5585e2f57
-       5181448596808493L, // 1268800308e32d
-       4920887247516739L, // 117b85585e3443
-       5360119236323197L, // 130b000308e77d
-       5471788386019861L, // 1370900308ea15
-       4645436678265319L, // 1081000308d9e7
-       4481655258710579L, // fec0aadb38233
-       5523900655878179L, // 139ff5585e4023
-       5203782426747811L, // 127cd00308e3a3
-       5375008456282711L, // 13188aadb39257
-       5226116256687127L, // 1291200308e417
-       5419676116161323L, // 13412aadb3932b
-       5218671646707367L, // 128a5aadb38ea7
-       5136780936929903L, // 123fe00308e26f
-       4556101358508169L, // 102fc00308d889
-       5263339306586077L, // 12b2faadb38fdd
-       4518878308609331L, // 100de5585e2d33
-       4533767528568833L, // 101b700308d801
-       4764550437941633L, // 10ed55585e3181
-       5509011435918673L, // 13926aadb39551
-       5166559376848937L, // 125af5585e3829
-       4489099868690317L, // ff2d00308d78d
-       4727327388042733L, // 10cb7aadb385ed
-       5330340796404157L, // 12efeaadb391bd
-       4801773487840397L, // 110f300308dc8d
-       5397342286222069L, // 132cdaadb392f5
-       5308006966464857L, // 12db9aadb39159
-       5084668667071573L, // 12107aadb38c55
-       4816662707799941L, // 111cbaadb38785
-       4704993558103493L, // 10b72aadb385c5
-       5114447106990601L, // 122b900308e209
-       4712438168083259L, // 10bdf00308db3b
-       5479232995999613L, // 137755585e3f7d
-       4660325898224963L, // 108e8aadb38543
-       5040001007192867L, // 11e7daadb38b23
-       4972999517375089L, // 11aaeaadb38a71
-       4853885757698843L, // 113e95585e331b
-       5315451576444613L, // 12e2600308e6c5
-       5412231506181583L, // 133a65585e3dcf
-       5144225546909639L, // 1246a5585e37c7
-       4548656748528367L, // 1028faadb382ef
-       4615658238346273L, // 1065eaadb38421
-       5583457535716339L, // 13d6200308ebf3
-       4474210648730791L, // fe545585e2ca7
-       4838996537739323L, // 11310aadb3883b
-       4600769018386699L, // 1058600308d90b
-       4742216608002253L, // 10d905585e30cd
-       4570990578467701L, // 103d4aadb38375
-       5032556397213109L, // 11e115585e35b5
-       5025111787233371L, // 11da500308e05b
-       5568568315756819L, // 13c895585e4113
-       5174003986828717L, // 1261baadb38dad
-       4675215118184491L, // 109c15585e302b
-       5494122215959133L, // 1384e00308ea5d
-       4980444127354847L, // 11b1b00308dfdf
-       4697548948123739L, // 10b065585e305b
-       4779439657901123L, // 10fae00308dc43
-       5129336326950151L, // 12391aadb38d07
-       5464343776040087L, // 1369caadb39497
-       5248450086626447L, // 12a5700308e48f
-       4905998027557141L, // 116dfaadb38915
-       5047445617172633L, // 11eea00308e099
-       5345230016363663L, // 12fd75585e3c8f
-       5442009946100803L, // 13557aadb39443
-       4630547458305841L, // 107375585e2f31
-       5501566825938893L, // 138ba5585e3fcd
-       5077224057091819L, // 1209b5585e36eb
-       4913442637536913L, // 1174c00308de91
-       4935776467476299L, // 1189100308df4b
-       4541212138548581L, // 102235585e2d65
-       5404786896201841L, // 1333a00308e871
-       5159114766869153L, // 1254300308e2a1
-       5010222567273893L, // 11ccc5585e35a5
-       5531345265857969L, // 13a6baadb395b1
-       4757105827961849L, // 10e6900308dbf9
-       4563545968487959L, // 103685585e2e17
-       4719882778062997L, // 10c4b5585e3095
-       4928331857496557L, // 11824aadb389ed
-       5322896186424389L, // 12e925585e3c45
-       5538789875837723L, // 13ad800308eb1b
-       4690104338143981L, // 10a9a00308daed
-       4943221077456049L, // 118fd5585e34b1
-       4987888737334627L, // 11b875585e3563
-       5300562356485079L, // 12d4d5585e3bd7
-       5367563846302937L, // 1311c5585e3cd9
-       5293117746505229L, // 12ce100308e60d
-       5255894696606263L, // 12ac35585e3a37
-       5211227036727601L, // 128395585e3931
-       5285673136525447L, // 12c74aadb39087
-       4526322918589091L, // 1014aaadb382a3
-       4593324408406963L, // 10519aadb383b3
-       5449454556080573L, // 135c400308e9bd
-       4995333347314369L, // 11bf3aadb38ac1
-       5107002497010847L, // 1224caadb38c9f
-       5382453066262463L, // 131f500308e7bf
-       5553679095797237L, // 13bb0aadb395f5
-       4898553417577403L, // 116735585e33bb
-       4682659728164237L, // 10a2daadb3858d
-       4771995047921369L, // 10f41aadb386d9
-       4585879798427209L, // 104ad5585e2e49
-       5069779447111979L, // 1202f00308e12b
-       4861330367678597L, // 11455aadb38885
-       4965554907395353L, // 11a425585e3519
-       5188893206788243L, // 126f45585e3893
-       4831551927759449L, // 112a45585e3259
-       5337785406383909L, // 12f6b00308e725
-       5092113277051363L, // 1217400308e1e3
-       5456899166060341L, // 136305585e3f35
-       5427120726141077L, // 1347f00308e895
-       5270783916565829L, // 12b9c00308e545
-       5561123705777023L, // 13c1d00308eb7f
-       4749661217982049L, // 10dfcaadb38661
-       5121891716970409L, // 123255585e37a9
-       5486677605979391L, // 137e1aadb394ff
+const int64_t ReRandomizer::m_primes64[] = {
+       7919787109669756829L, // 6de8 bc6a 5895 5f9d
+       8190338840038832831L, // 71a9edc7de997abf
+       7636937573374813723L, // 69fbda42c0d6e61b
+       8079658586706028951L, // 7020b6ad3f0c2997
+       7563150737819611069L, // 68f5b5865678afbd
+       9161865508182333647L, // 7f257c23571c98cf
+       8903611583739124583L, // 7b8ffb8fe2d2db67
+       7907489303743889767L, // 6dbd0ba046db0167
+       8657655465221782259L, // 78262bc680437af3
+       7821404662262819933L, // 6c8b3619cac26c5d
+       8719144494851117963L, // 79009fb8d8e7538b
+       7686128797078281971L, // 6aaa9d6b07c05ef3
+       8559273017814845539L, // 76c8a575f2708863
+       8128849810409497363L, // 70cf79d585f5a313
+       8854420360035656279L, // 7ae138679be96257
+       9038887448923662727L, // 7d70943ea5d4e987
+       7673830991152414909L, // 6a7eeca0f60600bd
+       7403279260783338683L, // 66bdbb437001e4bb
+       9124972090404732371L, // 7ea269c521ed7dd3
+       8596166435592446783L, // 774bb7d4279fa33f
+       8879015971887390451L, // 7b3899fbbf5e1ef3
+       8633059853370048097L, // 77ceca325ccebe61
+       8952802807442592961L, // 7c3ebeb829bc54c1
+       8620762047444181001L, // 77a319684b146009
+       8485486182259643099L, // 75c280b9881252db
+       7526257320042009869L, // 6872a3282149950d
+       8694548882999383631L, // 78a93e24b572964f
+       7464768290412674327L, // 67982f35c8a5bd17
+       7489363902264408529L, // 67ef90c9ec1a79d1
+       7870595885966288393L, // 6d39f94211abe609
+       9100376478552998239L, // 7e4b0830fe78c15f
+       8534677405963111397L, // 767143e1cefbcbe5
+       7415577066709205983L, // 66e96c0d81bc43df
+       7809106856336952853L, // 6c5f854fb9080e15
+       8805229136332187873L, // 7a32753f54ffe8e1
+       7932084915595623907L, // 6e146d346a4fbde3
+       8915909389664991689L, // 7bbbac59f48d39c9
+       8768335718554586333L, // 79af62e11fd0ccdd
+       8399401540778573443L, // 7490ab330bf9be83
+       7956680527447358099L, // 6e6bcec88dc47a93
+       7772213438559351497L, // 6bdc72f183d8f2c9
+       8448592764482041823L, // 753f6e5b52e337df
+       7784511244485218609L, // 6c0823bb95935131
+       9051185254849529807L, // 7d9c4508b78f47cf
+       7698426603004149029L, // 6ad64e35197abd25
+       8325614705223370843L, // 738a8676a19b885b
+       8214934451890567001L, // 72014f5c020e3759
+       8018169557076693449L, // 6f4642bae66851c9
+       8780633524480453421L, // 79db13ab318b2b2d
+       8940505001516725891L, // 7c130dee1801f683
+       8497783988185510157L, // 75ee318399ccb10d
+       7513959514116142799L, // 6846f25e0f8f36cf
+       7624639767448946537L, // 69d02978af1c8769
+       9223354537811669137L, // 7ffff015afc07091
+       7390981454857471589L, // 66920a795e478665
+       7993573945224959303L, // 6eeee126c2f39547
+       7600044155597212391L, // 6978c7e48ba7cae7
+       7833702468188687047L, // 6cb6e6e3dc7ccac7
+       7550852931893743991L, // 68ca04bc44be5177
+       8313316899297503759L, // 735ed5ac8fe12a0f
+       8301019093371636691L, // 733324e27e26cbd3
+       9198758925959934931L, // 7fa88e818c4bb3d3
+       8546975211888978467L, // 769cf4abe0b62a23
+       7723022214855883181L, // 6b2dafc93cef79ad
+       9075780866701264103L, // 7df3a69cdb0404e7
+       8227232257816434127L, // 722d002613c895cf
+       7759915632633484433L, // 6bb0c227721e9491
+       7895191497818022631L, // 6d915ad63520a2e7
+       8473188376333776041L, // 7596cfef7657f4a9
+       9026589642997795633L, // 7d44e374941a8b31
+       8669953271147649367L, // 7851dc9091fdd957
+       8104254198557763209L, // 707818416280e689
+       8337912511149237901L, // 73b63740b355e68d
+       8829824748183922019L, // 7a89d6d37874a563
+       8989696225220194277L, // 7cc1d1165eeb6fe5
+       7649235379300680787L, // 6a278b0cd2914453
+       9088078672627131179L, // 7e1f5766ecbe632b
+       8387103734852706359L, // 7464fa68fa3f6037
+       8116552004483630269L, // 70a3c90b743b44bd
+       8153445422261231567L, // 7126db69a96a5fcf
+       7501661708190275741L, // 681b4193fdd4d89d
+       8928207195590858807L, // 7be75d2406479837
+       8522379600037244329L, // 76459317bd416da9
+       8276423481519902413L, // 72dbc34e5ab20ecd
+       9137269896330599473L, // 7ece1a8f33a7dc31
+       7858298080040421193L, // 6d0e4877fff18749
+       7538555125967876929L, // 689e53f23303f341
+       7796809050411085667L, // 6c33d485a74daf63
+       8141147616335364457L, // 70fb2a9f97b00169
+       8792931330406320547L, // 7a06c475434589a3
+       9149567702256466567L, // 7ef9cb5945623a87
+       7747617826707617371L, // 6b85115d6064365b
+       8165743228187098633L, // 71528c33bb24be09
+       8239530063742301213L, // 7258b0f02582f41d
+       8756037912628719257L, // 7983b2170e166e99
+       8866718165961523363L, // 7b0ce931ada3c0a3
+       8743740106702852129L, // 7958014cfc5c1021
+       8682251077073516489L, // 787d8d5aa3b837c9
+       8608464241518313933L, // 7777689e395a01cd
+       8731442300776985039L, // 792c5082eaa1b1cf
+       7477066096338541471L, // 67c3dfffda601b9f
+       7587746349671345317L, // 694d171a79ed6ca5
+       9001994031146061461L, // 7ced81e070a5ce95
+       8251827869668168273L, // 728461ba373d5251
+       8436294958556174707L, // 7513bd914128d973
+       8891313777813257509L, // 7b644ac5d1187d25
+       9174163314108200743L, // 7f512ced68d6f727
+       8091956392631896121L, // 704c677750c68839
+       7735320020781750283L, // 6b5960934ea9d80b
+       7882893691892155529L, // 6d65aa0c23664489
+       7575448543745478239L, // 6921665068330e5f
+       8374805928926839249L, // 7439499ee88501d1
+       8030467363002560527L, // 6f71f384f822b00f
+       8202636645964699889L, // 71d59e91f053d8f1
+       8571570823740712651L, // 76f45640042ae6cb
+       7981276139299092239L, // 6ec3305cb139370f
+       8817526942258054961L, // 7a5e260966ba4731
+       8411699346704440571L, // 74bc5bfd1db41cfb
+       9014291837071928527L, // 7d1932aa82602ccf
+       8965100613368460023L, // 7c6a6f823b76b2f7
+       8706846688925250799L, // 78d4eeeec72cf4ef
+       9186461120034067873L, // 7f7cddb77a9155a1
+       7846000274114554117L, // 6ce297adee372905
+       8460890570407908911L, // 756b1f25649d962f
+       9063483060775397003L, // 7dc7f5d2c949a68b
  };
-const int ReRandomizer::m_countPrimes = sizeof ReRandomizer::m_primes
-       / sizeof(int);
+const int ReRandomizer::m_countPrimes = sizeof ReRandomizer::m_primes64
+       / sizeof ReRandomizer::m_primes64[0];
 const int ReNameScrambler::m_indexOfNodeChar[] = { -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, 11, 12,
@@ -209,7 +209,7 @@ ReRandomizer::seed_t ReRandomizer::hash(const QByteArray& text) {
        int ixPrimes = m_countPrimes / 2;
        rc *= text.at(0);
        for (int ix = text.length() - 1; ix > 0; ix--) {
-               rc = rc * m_primes[ixPrimes] * text.at(ix) * m_primes[ixPrimes - 1];
+               rc = rc * m_primes64[ixPrimes] * text.at(ix) * m_primes64[ixPrimes - 1];
                if ((ixPrimes -= 2) <= 0)
                        ixPrimes = m_countPrimes;
        }
@@ -228,17 +228,17 @@ void ReRandomizer::hash(const QByteArray& text, QByteArray& seed) {
        int textLength = text.length();
        for (int ix = maxTrg; ix >= 0; ix--) {
                last = trg[ix] = last * text.at(ix % textLength)
-                       + m_primes[ix % m_countPrimes] * text.at((ix + 1) % textLength);
+                       + m_primes64[ix % m_countPrimes] * text.at((ix + 1) % textLength);
        }
        // length password > length seed:
        for (int ix = maxTrg; ix < textLength; ix++) {
                last = trg[ix % maxTrg] ^= last * text.at(ix)
-                       + m_primes[ix % m_countPrimes];
+                       + m_primes64[ix % m_countPrimes];
        }
        // length password < length seed:
        for (int ix = textLength; ix <= maxTrg; ix++) {
                last = trg[ix] = last * text.at(ix % textLength)
-                       + m_primes[ix % m_countPrimes];
+                       + m_primes64[ix % m_countPrimes];
        }
        // mix of all seed entries:
        for (int ix = 0; ix <= maxTrg; ix++)
@@ -254,26 +254,40 @@ const QByteArray& ReRandomizer::name() const {
        return m_name;
 }
 
+/**
+ * Produces a random number which is very difficult to find out.
+ *
+ * @return     a random value not easy to find out
+ */
+ReRandomizer::seed_t ReRandomizer::pseudoTrueRandom(){
+       clock_t random = clock();
+       time_t random2 = time(NULL);
+       static int s_counter = 0;
+       void* dummy2 = malloc(1);
+       free(dummy2);
+       seed_t rc = (((seed_t) random2) << 31) + (seed_t) random
+               + ((seed_t) &s_counter << 9)
+               + ((-random ^ 0x20111958) ^ (seed_t(dummy2)));
+       rc = (rc * m_primes64[int(rc % m_countPrimes)]
+                       + (m_primes64[int((rc >> 13) % m_countPrimes)] >> 1))
+                       ^ m_primes64[++s_counter % m_countPrimes];
+       rc = (rc << 56) | (uint64_t(rc) >> (64 - 56));
+       return rc;
+}
+
 /**
  * @brief Returns a random number which is not predictable.
  *
  * @return a number which is not predictable
  */
 ReRandomizer::seed_t ReRandomizer::nearTrueRandom() {
-       seed_t rc = 0;
+       seed_t rc = pseudoTrueRandom();
 #if defined __linux__
        int fh = open("/dev/urandom", O_RDONLY);
-       char buffer[sizeof(seed_t)];
-       if (read(fh, buffer, sizeof buffer) > 0)
-       rc ^= *(seed_t*) buffer;
+       seed_t buffer;
+       if (read(fh, reinterpret_cast<char*>(&buffer), sizeof buffer) > 0)
+               rc ^= buffer;
        close(fh);
-#else
-       time_t random = time(NULL);
-       static int dummy = 5;
-       void* dummy2 = malloc(1);
-       free(dummy2);
-       rc = (((seed_t) random) << 31) + ((seed_t) &dummy << 9)
-               + ((-random ^ 0x20111958) ^ (seed_t(dummy2)));
 #endif
        return rc;
 }
@@ -535,8 +549,8 @@ void ReSingleSeedRandomizer::textToSeed(const QByteArray& text) {
  * @brief Constructor.
  */
 ReCongruentialGeneratorBase::ReCongruentialGeneratorBase() :
-               m_factor(214013),
-               m_increment(2531011) {
+               m_factor(0x79009fb8d8e7538bL),
+               m_increment(7809106856336952853L) {
 }
 
 /**
@@ -621,7 +635,7 @@ ReRotateRandomizer::ReRotateRandomizer() :
 
 ReRandomizer::seed_t ReRotateRandomizer::nextSeed64() {
        seed_t rc = ReCongruentialGenerator::nextSeed64();
-       rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffll);
+       rc = ((rc << 33) | (uint64_t(rc) >> 31));
        ++m_counter;
        return rc;
 }
@@ -640,8 +654,8 @@ ReMultiSeedRandomizer::ReMultiSeedRandomizer(int countSeeds, const char* name) :
        m_seeds = reinterpret_cast<seed_t*>(m_seedBuffer.data());
        for (int ix = 0; ix < m_countSeeds; ix++) {
                int ixPrimes = ix % m_countPrimes;
-               m_seeds[ix] = m_primes[ixPrimes] * (2 * ix + 1)
-                       + (seed_t(m_primes[m_countPrimes - 1 - ixPrimes]) << 32);
+               m_seeds[ix] = m_primes64[ixPrimes] * (2 * ix + 1)
+                       + (seed_t(m_primes64[m_countPrimes - 1 - ixPrimes]) << 32);
        }
        // assignment does not work: copy on write
        m_startSeed.resize(m_seedBuffer.length());
@@ -655,10 +669,10 @@ ReMultiSeedRandomizer::ReMultiSeedRandomizer(int countSeeds, const char* name) :
 ReRandomizer::seed_t ReMultiCongruentialGenerator::nextSeed64() {
        m_currentSeed = (m_currentSeed + 1) % m_countSeeds;
        int ixFactor = int((m_seeds[m_currentSeed] >> 7) % (m_countPrimes - 1));
-       seed_t rc = m_seeds[m_currentSeed] * m_primes[ixFactor]
-                       + (m_primes[ixFactor + 1] >> 1);
+       seed_t rc = m_seeds[m_currentSeed] * m_primes64[ixFactor]
+                       + (m_primes64[ixFactor + 1] >> 1);
        m_seeds[m_currentSeed] = rc;
-       rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffLL);
+       rc = (rc << 33) | (uint64_t(rc) >> (64-33));
        ++m_counter;
        return rc;
 }
@@ -938,7 +952,7 @@ bool ReByteScrambler::decodeContent(const QByteArray& source,
                int64_t* trg = reinterpret_cast<int64_t*>(target.data());
                int count = (source.length() - offset) / sizeof(int64_t);
                const int64_t* src = reinterpret_cast<const int64_t*>(source.constData() + offset);
-               int64_t last = ReRandomizer::m_primes[0];
+               int64_t last = ReRandomizer::m_primes64[0];
                for (int ix = 0; ix < count; ix++) {
                        int64_t last2 = last;
                        last = *src++;
@@ -979,7 +993,7 @@ void ReByteScrambler::encodeContent(const QByteArray& source,
        int64_t* trg = reinterpret_cast<int64_t*>(target.data());
        int count = source.length() / sizeof(int64_t);
        const int64_t* src = reinterpret_cast<const int64_t*>(source.constData());
-       int64_t last = ReRandomizer::m_primes[0];
+       int64_t last = ReRandomizer::m_primes64[0];
 
        for (int ix = 0; ix < count; ix++) {
                int64_t rand = m_contentRandom.nextSeed64();
index c296edb9e67e48247093c2a29e10de3d049d690e..c2c48f428e781e1d5e571f03df4e19b09cb675db 100644 (file)
@@ -70,13 +70,14 @@ public:
 public:
        static seed_t hash(const QByteArray& text);
        static void hash(const QByteArray& text, QByteArray& seed);
+       static seed_t pseudoTrueRandom();
 
 protected:
        QByteArray m_name;
        int m_counter;
 public:
        // the first 125 prime numbers
-       static const int64_t m_primes[];
+       static const int64_t m_primes64[];
        static const int m_countPrimes;
 };
 
@@ -122,11 +123,12 @@ class ReCongruentialGenerator: public ReSingleSeedRandomizer,
        public ReCongruentialGeneratorBase {
 public:
        ReCongruentialGenerator();
+public:
+       virtual seed_t nextSeed64();
 protected:
        ReCongruentialGenerator(const char* name);
 protected:
        friend class ReShiftRandom;
-       virtual seed_t nextSeed64();
 };
 
 /**
index 48c8840c2d748c990520f30fdd9bd58d07e20e87..32181c31e66cfa2d438754bd8a9828eddf2438a4 100644 (file)
@@ -234,6 +234,102 @@ public:
                        checkContent(src, scrambler);
                }
        }
+       void testShuffle(){
+               ReKISSRandomizer random;
+               const int MAX = 177;
+               int64_t alField[MAX];
+               int anField[MAX];
+               unsigned char acField[MAX];
+               typedef struct info {
+                       int64_t m_i64[8];
+               } big_t;
+               big_t aoField[MAX];
+               bool nHit[MAX];
+               bool lHit[MAX];
+               bool cHit[MAX];
+               bool oHit[MAX];
+               memset(nHit, 0, sizeof nHit);
+               memset(lHit, 0, sizeof lHit);
+               memset(cHit, 0, sizeof cHit);
+               memset(oHit, 0, sizeof oHit);
+               int ix, ix2;
+               for (ix = 0; ix < MAX; ix++){
+                       anField [ix] = ix + 1000;
+                       alField [ix] = ix + 10000;
+                       acField [ix] = ' ' + ix;
+                       for (ix2 = 0; ix2 < 8; ix2++)
+                               aoField[ix].m_i64[ix2] = ix2 * 100 + 1000 + ix;
+               }
+               random.shuffle(alField, MAX, sizeof alField[0]);
+               random.shuffle(acField, MAX, sizeof acField[0]);
+               random.shuffle(anField, MAX, sizeof anField[0]);
+               random.shuffle(aoField, MAX, sizeof aoField[0]);
+
+               for (ix = 0; ix < MAX; ix++){
+                       if (anField[ix] >= 1000 && anField[ix] < 1000 + MAX)
+                               nHit[anField[ix] - 1000] = true;
+                       else
+                               checkT(false);
+
+                       if (alField[ix] >= 10000 && anField[ix] < 10000 + MAX)
+                               lHit[alField[ix] - 10000] = true;
+                       else
+                               checkT(false);
+
+                       if (acField[ix] >= ' ' && acField[ix] < ' ' + MAX)
+                               cHit[acField[ix] - ' '] = true;
+                       else
+                               checkT(false);
+
+                       if (aoField[ix].m_i64[0] >= 1000 && aoField[ix].m_i64[0] < 1000 + MAX){
+                               oHit[aoField[ix].m_i64[0] - 1000] = true;
+                               int ix3 = aoField[ix].m_i64[0] - 1000;
+                               for (int ix2 = 0; ix2 < 8; ix2++){
+                                       checkEqu(aoField[ix].m_i64[ix2], (int64_t) ix2 * 100 + 1000 + ix3);
+                               }
+                       } else
+                               checkT(false);
+
+               }
+               for (ix = 0; ix < MAX; ix++){
+                       checkT(nHit[ix]);
+                       checkT(lHit[ix]);
+                       checkT(cHit[ix]);
+                       checkT(oHit[ix]);
+               }
+       }
+       void testRealRandom(){
+               int64_t seeds[10];
+
+               for (int ix = 0; ix < 10; ix++)
+                       seeds[ix] = ReRandomizer::pseudoTrueRandom();
+               log("nearRealRandom:");
+               for (int ix = 0; ix < 10; ix++)
+                       printf("%016llx\n", (long long) seeds[ix]);
+       }
+       void testNextString(){
+               ReCongruentialGenerator rand;
+               ReXorShift64Randomizer rand2;
+               ReMultiCongruentialGenerator rand3(2);
+               ReKISSRandomizer rand4;
+               QByteArray buffer;
+               printf("nextString():\n");
+               printf("LCG: %s\n", rand.nextString(80, 80, buffer));
+               printf("XOR: %s\n", rand2.nextString(80, 80, buffer));
+               printf("MLC: %s\n", rand3.nextString(80, 80, buffer));
+               printf("KIS: %s\n", rand4.nextString(80, 80, buffer));
+               for (int ix = 0; ix < 500000; ix++){
+                       rand.nextSeed64();
+                       rand2.nextSeed64();
+                       rand3.nextSeed64();
+                       rand4.nextSeed64();
+               }
+               printf("LCG: %s\n", rand.nextString(80, 80, buffer));
+               printf("XOR: %s\n", rand2.nextString(80, 80, buffer));
+               printf("MLC: %s\n", rand3.nextString(80, 80, buffer));
+               printf("KIS: %s\n", rand4.nextString(80, 80, buffer));
+       }
+
        void special(){
                ReKISSRandomizer rand;
                rand.dump();
@@ -243,6 +339,9 @@ public:
        }
 
        virtual void run(void) {
+               testNextString();
+               testRealRandom();
+               testShuffle();
                special();
                testContentEncoding();
                testNamesEncoding();