**Edit suggested by fgrieu**: I have one hundred integers in $\{0,1,2,3,4,5\}$ which I suspect are consecutive values of $⌊𝑥_𝑛/2^{16}⌋\bmod6$ computed as $𝑥_{𝑛+1}:=𝑎⋅𝑥_𝑛+𝑏\bmod𝑚$, with $𝑚=2^{31}$, and $(𝑎,𝑏)∈{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(𝑎,𝑏)$ used, and predict what follows in the sequence? ----------------------------- **Question about "A competent implementation in a compiled language would take like a second on a modern desktop PC."** I wrote some code but they are expected to run 20 hours. I am trying to find the random seed. First, I input my data in an array. Since I don't know my first data is what-th number generated by the server, I need to find it out. I only know the server shut down every thursday 2:00pm, and restart around 2:45-3:45pm the same day. When the server is on, ir generates 3 numbers every 45 seconds. The data I have is collected on fri 1:50 am, so my first data maybe the 2400-2640th number of the LCG. I first run the rand 2399 times to discard the first 2399 numbers. Next, I loop 241 times to find my first data is what-th number generated by the server. (the uncertainity of the server restart time 2:45-3:45pm, 240 numbers per hour) My method is: If 2400th x's bit 16 equal to bit 0 of $y_1$, then I check 2401th x's bit 16 and bit 0 of $y_2$, and so on. If there is unequal, break the loop then start another loop, compare 2401th x and bit 0 of $y_1$. I just started to learn c++ two weeks ago, please forgive my ignorance. #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <iostream> #include <inttypes.h> using namespace std; const int RESULT[3][7] = { {0,1,0,1,1,1,1}, {1,0,1,0,0,0,0}, {0,1,1,0,1,0,0} }; static unsigned long x; int test_rand(void) { x = 214013 * x + 2531011; // or is it 22695477*x+1 return (int)((x >> 16) & 0x7FFF); }; int onlyx16(void) { x = 214013 * x + 2531011; // or is it 22695477*x+1 return (x >> 16) & 1; }; void chk_seed(unsigned long seed) { int d1[241]{}; int d2[241]{}; int d3[241]{}; x = seed; for (int i = 0; i < 2399; i++) { test_rand(); } for (int i = 0; i < 241; i++) { d1[i] = onlyx16(); d2[i] = onlyx16(); d3[i] = onlyx16(); }; int correct = 0; for (int k = 0; k < 236; k++) { correct = 0; for (int i = 0; i < 7; i++) { if ((d1[i + k]) == RESULT[0][i]) { correct += 1; } else { correct = 0; break; }; if ((d2[i + k]) == RESULT[1][i]) { correct += 1; } else { correct = 0; break; }; if ((d3[i + k]) == RESULT[2][i]) { correct += 1; } else { correct = 0; break; }; }; if (correct == 21) { printf("seed 0x%d is OK\n", seed); printf("results forecast:\n"); for (int round = 0; round < 5; round++) { printf("round%d ", round + 1); int new_d[3]{}; for (int i = 0; i < 3; i++) { new_d[i] = test_rand()% 6; printf("%d", new_d[i]); }; printf("\n"); } }; } }; int main() { for (unsigned long seed = 0; seed < 0x100000000; seed++) chk_seed(seed); }; ----------------------------- $x_{n+1} = (a \cdot x_{n} + b) \mod m$ In normal situation, $x_{n+1}$ and $x_n$ are known. But now I only know $x_n\mod 6$ and $x_{n+1}\mod 6$. I have searched many website on google but I only find one question that talked about this problem. https://crypto.stackexchange.com/questions/2086/predicting-values-from-a-linear-congruential-generator However, it is not very clear and I still don't know what should I do after reading that. I hope someone can provide some math or example code, so that I can learn from trial and error. I want to find a,b,m then use a C++ source code I found here to brute-force the seed. I found an answer here that talked about how to find m, but I don't know $x_{n+1}$ and $x_n$. https://security.stackexchange.com/questions/4268/cracking-a-linear-congruential-generator I am new to this topic, but I desperately wanted to crack this PRNG, this PRNG made me suffered a lot, I decided to learn programming because of this PRNG. Thank you for your help!