\myheading{Can rand() generate 10 consecutive zeroes?} \leveldown{} I've always been wondering, if it's possible or not. As of simplest linear congruential generator from MSVC's rand(), I could get a state at which rand() will output 8 zeroes modulo 10: \lstinputlisting[style=custompy]{\CURPATH/LCG10.py} \begin{lstlisting} sat [state3 = 1181667981, state4 = 342792988, state5 = 4116856175, state7 = 1741999969, state8 = 3185636512, state2 = 1478548498, state6 = 4036911734, state1 = 286227003, state9 = 1700675811] \end{lstlisting} This is a case if, in some video game, you'll find a code: \begin{lstlisting} for (int i=0; i<8; i++) printf ("%d\n", rand() % 10); \end{lstlisting} ... and at some point, this piece of code can generate 8 zeroes in row, if the state will be 286227003 (decimal). Just checked this piece of code in MSVC 2015: \begin{lstlisting} // MSVC 2015 x86 #include int main() { srand(286227003); for (int i=0; i<8; i++) printf ("%d\n", rand() % 10); }; \end{lstlisting} Yes, its output is 8 zeroes! What about other modulos? I can get 4 consecutive zeroes modulo 100: \lstinputlisting[style=custompy]{\CURPATH/LCG100.py} \begin{lstlisting} sat [state3 = 635704497, state4 = 1644979376, state2 = 1055176198, state1 = 3865742399, state5 = 1389375667] \end{lstlisting} However, 4 consecutive zeroes modulo 100 is impossible (given these constants at least), this gives ``unsat'': \url{\RepoURL/\CURPATH/LCG100_v1.py}. ... and 3 consecutive zeroes modulo 1000: \lstinputlisting[style=custompy]{\CURPATH/LCG1000.py} \begin{lstlisting} sat [state3 = 1179663182, state2 = 720934183, state1 = 4090229556, state4 = 786474201] \end{lstlisting} What if we could use rand()'s output without division? Which is in 0..0x7fff range (i.e., 15 bits)? As it can be checked quickly, 2 zeroes at output is possible: \lstinputlisting[style=custompy]{\CURPATH/LCG.py} \begin{lstlisting} sat [state2 = 20057, state1 = 3385131726, state3 = 22456] \end{lstlisting} \myheading{UNIX time and srand(time(NULL))} Given the fact that it's highly popular to initialize LCG PRNG with UNIX time (i.e., \TT{srand(time(NULL))}), you can probably calculate a moment in time so that LCG PRNG will be initialized as you want to. For example, can we get a moment in time from now (5-Dec-2017) till 12-Dec-2017 (that is one week from now), when, if initialized by UNIX time, rand() will output as many similar numbers (modulo 10), as possible? \lstinputlisting[style=custompy]{\CURPATH/LCG10_time.py} Yes: \begin{lstlisting} sat [state3 = 2234253076, state4 = 497021319, state5 = 4160988718, c = 3, state2 = 333151205, state6 = 46785593, state1 = 1512500810, state7 = 1158878744] \end{lstlisting} If \TT{srand(time(NULL))} will be executed at \TT{Tue Dec 5 21:06:50 EET 2017} (this precise second, UNIX time=1512500810), a next 6 \TT{rand() \% 10} lines will output six numbers of 3 in a row. Don't know if it useful or not, but you've got the idea. \myheading{etc:} The files: \url{\RepoURL/\CURPATH}. Further work: check glibc's \TT{rand()}, Mersenne Twister, etc. A simple 32-bit LCG (as described) can be checked using simple brute-force, I think. \myheading{Fun story} The software checked protection key (dongle) randomly, from time to time. This code snippet is from a real one: \begin{lstlisting}[style=customc] void init_all() { ... srand(time(NULL)); ... }; ... void check_protection_thread() { // get in 0..9 range int t=(int)((double)rand()/3276); if (t== 5) { check protection } }; \end{lstlisting} Perhaps, we can find the most optimal UNIX time to start the software, so the protection will not be checked as long as possible... \myheading{Further reading} Breaking JavaScript's \ac{PRNG} (XorShift128+):\\ \url{https://blog.securityevaluators.com/hacking-the-javascript-lottery-80cc437e3b7f}. \levelup{}