Академический Документы
Профессиональный Документы
Культура Документы
(Email: KazukiAmakawa@gmail.com)
Abstract: This paper introduced some algorithm to generate RNG sequence. First, it
used several methods to get the TRNG quickly and easy. Then it introduced some
popular algorithm to get the PRNG. Then, used the method of Monte Carlo, it give
some ways to get RNG sequence satisfied confident distribution in 1-dimension or
higher dimension as well as have some confident relation. At last, this paper
introduced some application in science and production, especially in science
researching.
Catalogue
1 Introduction02
2 The Algorithm of True Random Number Generation02
3 The Algorithm of Pseudo Random Number Generation05
3.1 Middle-square method...06
3.2 Linear congruential generator....07
3.3 Pseudorandom binary sequence.....08
4 Mersenne Twister and the evaluation of RNG sequence09
5 Random Number Sequence Transformation with Monte Carlo Method16
5.1 The Generation of 1-Dim Mean Distribution and 2-Dim Independent
Distribution....16
5.2 1-Dim Normal Distribution Transformation......17
6 The application of Random Number Generation ...19
8 Appendix..........20
10.1 The code of generating TRNG by CPU clock (in cpp).20
10.2 The code of generating TRNG by CPU clock (in Assembly & cpp)21
10.3 The code of generating TRNG by moving mouse (in Python) 22
10.4 The code of generating PRNG by LCG method (in Python)24
Reference.25
-1-
1 Introduction
With the development of information and technology, we use more mathematic
method in daily production than before. An historical problem, the generation of
random number, also become a new problem we have to face. Believe it or not, we
use these algorithm every day, when you sent an Email to your master, or login an
address to have fun. Whenever we need security and secrecy, we need Random
Number Generation (RNG).
As a good RNG is so important for us to save our information security, the
mathematic method to generate RNG also become an important activity. Not only
need we use it in our daily life, but also in our science research.
This article will introduce the mathematic method to generate RNG with algorithm.
We will also try to implement these algorithm. We will discuss the same in these
Distribution. And in the Appendix, we will also discuss the advance and shortcoming
of these RNG algorithm.
We will also introduce some usage of RNG, especially in Molecular Dynamics,
which is the main subject our SRTP group is studying.
As for the computing language, we will use Python at most time. And there are
several reasons for us to use it:
1st: We have to control the hardware, so it is difficult for us to you Matlab;
2nd: We can use C & CPP directly in Python.
3rd: It is easy in both writing and reading. It is familiar with the language we used in
the daily life.
4th: Python have better GUI to control hardware. It is easier than C as well as have
better compatibility.
5th: Python is rapid enough for the most calculation in this paper.
However, to make some program speedily enough, we will still use CPP and
Assembly sometimes.
-2-
sequences of apparently random results, which are in fact completely determined by a
shorter initial value, known as a seed value or key. Both methods have different
advantage and shortcoming. And we will first introduce the first kind of random
number generation, the True Random Number Generation (TRNG).
At the first of all, we will define what RNG is, and the different between TRNG
and Pseudo Random Number Generation (PRNG).
And now we can get the different between TRNG and PRNG:
1st: PRNG can be expected by the seed and the algorithm;
2nd: Usually, it is difficult to predict the next number in a PRNG;
3rd: It is easier and cheaper for computer to generate PRNG;
4th: TRNG have better security.
So in this section, we will introduce how to generate a TRNG. Before that, we will
introduce some methods to generate RNG.
-3-
As we introduced before, we can generate RNG by the physical methods. However,
this kind of generation method always expensive. For example, you can generate
RNG by the moving of atom, and you need expensive device to make it true.
Of course, we can use the moving of mouse to make the RNG quickly and cheap.
Or use the clock of CPU to get the RNG. We will discuss these later.
Method 4: By Humaniii
It is the most expensive and slow method, For example, you can generate RNG by
throwing coin, and obvious it is difficult to get enough large sum of RNG rapidly.
*/
And now we will use the CPU clock to generate a TRNG.
As all we know, at the time the CPU is turn on, these is a atom clock to remember
the time of CPU. And we can get the time between the programming is running. As
the parameter which can effect CPU are complex, and we almost cannot predict the
next random number we will get. We can believe that this random number sequence is
a TRNG sequence.
We will give the Pseudo Code in the main article, and we will also give our
programming code in the end of the article:
% Sample Code 2.1: The algorithm of generating TRND with CPU clock.
/*-----------------------------------------------------------------------------------------------------
void CPU_TRNG (int TOTAL){
for (int i = 0; i < TOTAL; i ++){
TimeBegin = CPU_Time;
Run the Programming;
TimeEnd = CPU_Time;
TimeLen = TimeEnd - TimeBegin;
TRNG_Number = TimeLen % 10;
print(%d, &TRNG_Number);
-4-
}
return ;
}
-----------------------------------------------------------------------------------------------------*/
However, when we ran this algorithm to make TRNG, we used at least 12 minutes to
get 10000 numbers. It is too slow. So we also implement this algorithm in both CPP
and Assembly.
And we also used the location of mouse to make the TRNG.
% Sample Code 2.2: The algorithm of generating TRND with mouse moving.
/*-----------------------------------------------------------------------------------------------------
void Mouse_TRNG (int TOTAL){
printf ("Now, moving your mouse rapidly");
for (int i = 0; i < TOTAL; i ++){
Local.x = Mouse.x;
Locay.y = Mouse.y;
TRNG_Number1 = Local.x % 10;
TRNG_Number2 = Local.y % 10;
printf ("%d %d", TRNG_Number1, TRNG_Number2);
}
return ;
}
-----------------------------------------------------------------------------------------------------*/
Obvious we still have some problem in the second method. For example, if someone
is lazy enough and he or she never move mouse during the program is running, then
we well get a series of numbers which actually have two numbers.
So that, we have to do some change, such as use the CPU time in the same to
generate TRNG or other methods. In the sample code in the end of the article, we also
used a series of conclusion to make sure even in this occasion, we still can get a RNG
sequence. Of course, this sequence may not so random.
-5-
3.1 Middle-square method
This is the easiest method to get PRNG, we even neednt any program language.
Only Excel is enough.
-6-
And we can try it in Excel.
However this algorithm still have some problem, for example, if we let m = 2 and
seed = 23002501, Then this algorithm is not so random.
Table3.2 MQM Error
m 2 Seed 23002501
LoopLong 8
No. PRNG Middle Square m
0 5 0025 23002501 2
1 5 25 625 2
2 5 25 625 2
3 5 25 625 2
4 5 25 625 2
5 5 25 625 2
(Of course, if we need too many random number, using a program is better than
using Excel. Because it is faster and safety.)
In this occasion, we find that the period of the PRNG sequence is too short and we
cannot use this algorithm. That means, we cannot always get good RNG sequence
with this algorithm.
So what is good RNG and how can we get better RNG sequence. We will discuss
this question in the next section, but now, we will introduce some better algorithm to
get PRNG sequence.
-7-
A (0< A <m) is increment, and B (0 B<m) is multiplier. All of these
parameters are integer
If B = 0, the generator is often called a multiplicative congruential generator
(MCG), or Lehmer RNG. If B 0, the method is called a mixed congruential
generator.v
And it is easy for us to get this algorithm.
/*-----------------------------------------------------------------------------------------------------
const int A, B, m;
void LCG (int TOTAL, long long seed){
Number = seed
for (int i = 0; i < TOTAL; i ++){
Number = (A + B * Number) % m;
PRNG_Number = Number;
printf("%d", &PRNG_Number);
}
return ;
}
-----------------------------------------------------------------------------------------------------*/
It is obvious that this algorithm have the source of Euclidean division and
congruence. There is no doubt that it is fast and require minimal memory to retain
state. Nevertheless, for some applications LCGs may be a good option. For instance,
in an embedded system, the amount of memory available is often severely limited.
But, this method still have some problem.
1st: LCGs should not be used for applications where high-quality randomness is
critical. For example, it is not suitable for a Monte Carlo simulation because of the
serial correlation.
2nd: They also must not be used for cryptographic applications.
3rd: LCGs tend to exhibit some severe defects. For instance, if an LCG is used to
choose points in an n-dimensional space, the points will lie on.
4th: A further problem of LCGs is that the lower-order bits of the generated
sequence have a far shorter period than the sequence as a whole if m is set to a power
of 2.
We will give the sample code in the appendix.
-8-
3.3 Pseudorandom binary sequencevi
And now we will get the third method to get PRNG sequence.
Pseudorandom binary sequence (PRBS) is a binary sequence that, while generated
with a deterministic algorithm, is difficult to predict vii and exhibits statistical behavior
similar to a truly-random sequence. PRBS are used in telecommunication, encryption,
simulation, correlation technique and time-of-flight spectroscopy.
If we have a binary sequence, let it is
a j= {0, 1 } , for j=0,1, 2 N1
Where N is the length of this sequence.
Then we definite a function:
N 1
C ( v )= a j a j+ v
j=0
It seem difficult in formula form. However, as we used the bit calculation, it is easy
and short.
% Sample Code 3.3: PRBS-PRNG
/*-----------------------------------------------------------------------------------------------------
//All number without TOTAL and PRNG_Number are binary number
//PRNG_Number is hes number
void PRBS (int TOTAL, int start, int p, int q){
//p, q is the defined by m and c
Number = start;
for (int i = 1; i < TOTAL; i++) {
NewBit = (((a >> (p-1)) ^ (a >> (q-1))) & 1);
PRNG_Number = ((Number << 1) | NewBit) & 0xffff;
printf ("%x ", a);
}
return ;
}
-----------------------------------------------------------------------------------------------------*/
-9-
4 Mersenne Twister and the evaluation of RNG sequence
Although Mersenne Twister (MT) is a kind of PRNG algorithm, we will still discuss
it in this new section. We will introduce not only MT but also the evaluation of RNG
The Mersenne Twister was developed in 1997 by Makoto Matsumoto and Takuji
Nishimura.viii It was designed specifically to rectify most of the flaws found in older
PRNGs. It was the first PRNG to provide fast generation of high-quality pseudo
random integers.
This algorithm is based on Mersenne prime. Before we research this algorithm, we
will introduce what is Mersenne prime.
- 10 -
u , d , l : additional Mersenne Twister tempering bit shifts/masks.
- 11 -
w
improve lower-bit equidistribution. From the property of TGFSR, s +t> 2 1 is [ ]
required to reach the upper bound of equidistribution for the upper bits.
The coefficients for MT19937 are:
(w, n, m, r) = (32, 624, 397, 31)
a = 9908B0DF16
(u, d) = (11, FFFFFFFF16)
(s, b) = (7, 9D2C568016)
(t, c) = (15, EFC6000016)
l = 18
Note that 32-bit implementations of the Mersenne Twister generally
have d = FFFFFFFF16. As a result, the d is occasionally omitted from the algorithm
description, since the bitwise and with d in that case has no effect.
And we will give the pseudo code for this algorithm:
int y = MT[index];
y = y ^ ((y >> u) & d);
y = y ^ ((y << s) & b);
y = y ^ ((y << t) & c);
y = y ^ (y >> l);
index = index + 1;
return (lowest w bits of (y));
}
- 13 -
Fig 4.1 The algorithm of MT
This algorithm is so long, and is also used the bit calculation. Is it better than other
algorithm? Before we discuss this question, we will discuss how to evaluating an
RNG algorithm first.
There several ways to test a RNG sequence is good or not.
Birthday spacings: Choose random points on a large interval. The spacings
between the points should be asymptotically exponentially distributed.[1] The name is
based on the birthday paradox.
Overlapping permutations: Analyze sequences of five consecutive random
numbers. The 120 possible orderings should occur with statistically equal probability.
Ranks of matrices: Select some number of bits from some number of random
numbers to form a matrix over {0,1}, then determine the rank of the matrix. Count the
ranks.
Monkey tests: Treat sequences of some number of bits as "words". Count the
overlapping words in a stream. The number of "words" that do not appear should
follow a known distribution. The name is based on the infinite monkey theorem.
Count the 1s: Count the 1 bits in each of either successive or chosen bytes.
Convert the counts to "letters", and count the occurrences of five-letter "words".
Parking lot test: Randomly place unit circles in a 100 100 square. A circle is
successfully parked if it does not overlap an existing successfully parked one. After
12,000 tries, the number of successfully parked circles should follow a certain normal
distribution.
Minimum distance test: Randomly place 8,000 points in a 10,000 10,000
square, then find the minimum distance between the pairs. The square of this distance
should be exponentially distributed with a certain mean.
- 14 -
Random spheres test: Randomly choose 4,000 points in a cube of edge 1,000.
Center a sphere on each point, whose radius is the minimum distance to another point.
The smallest sphere's volume should be exponentially distributed with a certain mean.
The squeeze test: Multiply 231 by random floats on (0,1) until you reach 1. Repeat
this 100,000 times. The number of floats needed to reach 1 should follow a certain
distribution.
Overlapping sums test: Generate a long sequence of random floats on (0,1). Add
sequences of 100 consecutive floats. The sums should be normally distributed with
characteristic mean and variance.
Runs test: Generate a long sequence of random floats on (0,1). Count ascending
and descending runs. The counts should follow a certain
distribution.
The craps test: Play 200,000 games of craps, counting
the wins and the number of throws per game. Each count
should follow a certain distribution.
However, as there are so many methods to discuss a
RNG sequence good or not, we will use the method most
easy and cheaper. To discuss them with figure.
With the figure above, there is no doubt that rand function in C# is better than php,
because we can find the discipline easily in Fig 4.2.
Of course, that is only an introduction of the method of figure. We will use this
method more mathematics.
We had make a figure like this in 3.2 LCG. And now, we will discuss why MT is
better algorithm than others.
Now we get two area in Fig 3.1
62 3
The area of red: V r 7253 =8.5 10 .
45 3
The are of blue: V b 7253 =6.2 10 .
3
And the true volume is 8.333 10 .
- 15 -
If we use MT in the same way, then we can get figure like Fig 4.5.
61 3
The area of red: V r 7253 =8.4 10 .
64 3
The are of blue: V b 7253 =8.8 10 .
3
And the true volume is 8.333 10 .
Carlo Method
5.1 The Generation of 1-Dim Mean Distribution and 2-Dim
Independent Distribution
- 16 -
Now, we will research how to get RNG sequence which satisfied the confident
distribution. And we will get a random number satisfied the 1-Dim Mean Distribution
and 2-Dim Independent Distribution, which is the easiest distribution we will build.
We will use TRNG sequence which generated by mouse and CPU clock. If we need
too much random number (rather than 100,000), we will use MT method to get the
PRNG sequence.
Obvious, all the RNG sequences, except the TRNG sequence we got by the only
CPU clock method, are satisfied 1-Dim Mean Distribution.
As for 2-Dim Independ Distribution, it is same as a longer 1-Dim mean distribution
sequence. That means, we can get x sequence in the way we get 1-Dim Mean
Distribution, then we can get y sequence in the same way. Then we will get the
(x i , y i ) which satisfied 2-Dim Independent Distribution.
Then we will discuss something difficulty.
And now we have another problem, for example, in the way we got TRNG by
mouse and CPU clock, we got a sequence satisfied by single number from 0 to 9. If
we need a sequence, for example, satisfied by 0 to 987, then how to get the sequence?
An easy way to get a 3-bit number is, get all this number three times. That means,
for example, if we got a TRNG sequence like 345178329653283, then the first
number, 3, will become the unit of the first number. And the next, 4, will become the
tens of the first number. And then, 5, will become the hundreds of the first number.
And now we got the first random number, which is 543. And the next number is
871 Of course, we may get a number like 991, which do not satisfied the
condition. And if we get an random number like this, we can delete it.
And now, we will try to get some RNG sequence satisfied more difficult
distribution.
f ( x| , )= e
2 2
Where:
mean or expectation of the distribution (and also its median and mode).
is standard deviation
- 17 -
2 is variance.
And now we will introduce some method to get RNG sequence satisfied 1-Dim
Normal Distrbution.
return Z;
}
-----------------------------------------------------------------------------------------------------*/
- 18 -
Method 3 : Marsaglia Polar Algorithm
If U 1 ,U 2( [0,1]) satisfied 2-Dim Independent Distribution, then
2 ln ( s) 2 ln ( s)
U1
s
,U 2
s
2 2
are satisfied 1-dim normal distribution and dependence, where s=U 1+U 2
This algorithm is better than BMA because we do not need triangle calculation in
this algorithm.
% Sample Code 5.1: 1-Dim Normal Distribution by MPA
/*-----------------------------------------------------------------------------------------------------
double RNG_MPA(){
double V1, V2, S;
double X;
bool flag = 0;
if (flag == 0){
do {
double U1 = randon number
in [0, 1]
double U2 = randon number
in [0, 1]
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
}while( S >= 1 || S ==0);
X = V1 * sqrt (-2 * log(S) / S);
}
else X = V2 * sqrt(-2 * log(S) / S);
flag = !flag;
return X;
}
-----------------------------------------------------------------------------------------------------*/
You can get random number sequence satisfied 1-Dim Normal Distribution easier
in Python or CPP, because all of these programming language have the command to
established all these algorithm. And now, in Python, if you want to get 1-Dim Normal
Distribution sequence, you will use BMA. (The figure on the left is the test of this
function with 10,000,000 times experiment)
- 20 -
7 Appendix
7.1 The code of generating TRNG by CPU clock (in cpp)
//////////////////////////////////////////////////////////////////////////////////
//
// The System of Generating TRNG with CPU clock in cpp
// Copyright(c) by George Kazuki Amakawa Huayan Chen
//
//////////////////////////////////////////////////////////////////////////////////
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
using namespace std;
//Define
int fig[12];
int main(){
//Initialization
freopen("file.txt", "w", stdout);
memset(fig, 0, sizeof(fig));
- 21 -
}
cout << "\n";
for(int i = 0; i < 10; i ++)
cout << fig[i] << "\n";
return 0;
}
#include<iostream>
using namespace std;
void GetClockNumber (long high, long low);
void GetRunTime();
int main(){
long long HighStart,LowStart,HighEnd,LowEnd;
long long numhigh,numlow;
for(int LOP = 0; LOP < 10000; LOP ++){
__asm(
RDTSC
mov HighStart, edx
mov LowStart, eax
mov ax, 1
mov cx, 10000000
s: add ax, 1
loop s
mov HighEnd, edx
mov LowEnd, eax
- 22 -
sub eax, LowStart
cmp eax, 0b
jg L1
neg eax
jmp L2
L1: mov numlow, eax
L2: sbb edx, HighStart
mov numhigh, edx
)
__int64 timer =(numhigh << 32) + numlow;
cout<< timer << endl;
}
return 0;
}
- 23 -
#Variable Initial
owari = int(TOTAL)+20
Begin_Time = time.clock()
- 24 -
#Begin the mainloop
root.mainloop()
- 25 -
#Initialization
A = input("Now, input the parameter A: ")
B = input("Now, input the parameter B: ")
seed = input("Now, input the seed of ")
def LCG(modulus, a, c, seed = None):
if seed != None:
lcg.previous = seed
random_number = (lcg.previous * a + c) % modulus
lcg.previous = random_number
return random_number
lcg.previous = 2222
const int A, B, m;
void LCG (int TOTAL, long long seed){
Number = seed
for (int i = 0; i < TOTAL; i ++){
Number = (A + B * Number) % m;
PRNG_Number = Number;
printf("%d", &PRNG_Number);
}
return ;
}
Referance
- 26 -
i The MathWorks. "Common generation methods". Retrieved 2011-10-13
ii Jump up ^ The Numerical Algorithms Group. "G05 Random Number Generators" . NAG
Library Manual, Mark 23. Retrieved 2012-02-09
iii W. A. Wagenaar (1972). "Generation of random sequences by human subjects: a critical survey
of the literature". Psychological Bulletin. 77 (1): 6572. doi:10.1037/h0032060
iv "Linear Congruential Generators" by Joe Bolte, Wolfram Demonstrations Project
v Donald E. Knuth (6 May 2014). Art of Computer Programming, Volume 2: Seminumerical
Algorithms. Addison-Wesley Professional. pp. 4. ISBN 978-0-321-63576-1.
vi Paul H. Bardell, William H. McAnney, and Jacob Savir, "Built-In Test for VLSI: Pseudorandom
Techniques", John Wiley & Sons, New York, 1987.
vii "PRBS Pseudo Random Bit Sequence Generation". TTi. Retrieved 21 January 2016.
viii Matsumoto, M.; Nishimura, T. (1998). "Mersenne twister: a 623-dimensionally equidistributed
uniform pseudo-random number generator". ACM Transactions on Modeling and Computer
Simulation. 8 (1): 330. doi:10.1145/272991.272995.
ix Matsumoto, M.; Nishimura, T. (1998). "Mersenne twister: a 623-dimensionally equidistributed
uniform pseudo-random number generator". ACM Transactions on Modeling and Computer
Simulation. 8 (1): 330. doi:10.1145/272991.272995.
x Figure from the site: https://www.zhihu.com/question/20222653
xi P. L'Ecuyer and R. Simard, "TestU01: "A C library for empirical testing of random number
generators", ACM Transactions on Mathematical Software, 33, 4, Article 22 (August 2007).
xii Hiroshi Haramoto; Makoto Matsumoto; Takuji Nishimura; Franois Panneton; Pierre LEcuyer.
"Efficient Jump Ahead for F2-Linear Random Number Generators". Retrieved 12 Nov 2015.
xiii "mt19937ar: Mersenne Twister with improved initialization". hiroshima-u.ac.jp. Retrieved 4
October 2015.