-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.java
More file actions
101 lines (83 loc) · 3.87 KB
/
Copy pathMain.java
File metadata and controls
101 lines (83 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* To compile and run this code, make sure you have Java installed. Save the code in a file named Main.java.
* You also need to have Dieharder installed on your system to run the randomness tests.
*
* clear && javac Main.java && java Main
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
/**
* LCG random number generator tester using Dieharder suite.
*/
public class Main {
/** Pseudo-random number generator for constants selection and LCG seeding. */
private static final Random PRNG = new SecureRandom();
private static long a;
private static long aMin;
private static long aMax;
private static long c;
private static long cMin;
private static long cMax;
private static long m;
private static long mMin;
private static long mMax;
/** Sample size in number of generated bytes. */
private static long sampleSize;
public static void main(String[] args) throws IOException, InterruptedException {
/* Load configuration properties. */
Properties properties = new Properties();
InputStream input = Main.class.getClassLoader().getResourceAsStream("config.properties");
properties.load(input);
aMin = Long.parseLong(properties.getProperty("a.min", ""+1));
aMax = Long.parseLong(properties.getProperty("a.max", ""+((1L<<32)-1)));
cMin = Long.parseLong(properties.getProperty("c.min", ""+0));
cMax = Long.parseLong(properties.getProperty("c.max", ""+((1L<<32)-1)));
mMin = Long.parseLong(properties.getProperty("m.min", ""+(1L<<31)));
mMax = Long.parseLong(properties.getProperty("m.max", ""+(1L<<32)));
sampleSize = Long.parseLong(properties.getProperty("sample.size", ""+26214400));
/* Load tracking of the checked constants combinations. */
Set<String> tracking = new HashSet<>(Files.readAllLines(Paths.get("tracking.txt")));
String ticker = "";
byte[] values = new byte[(int)sampleSize*4];
while (true) {
/* Generate unique LCG constants combination. */
do {
a = aMin + ((Math.abs(PRNG.nextLong()) % (aMax - aMin + 1)));
c = cMin + ((Math.abs(PRNG.nextLong()) % (cMax - cMin + 1)));
m = mMin + ((Math.abs(PRNG.nextLong()) % (mMax - mMin + 1)));
ticker = String.format("%012d", a) + String.format("%012d", c) + String.format("%012d", m);
} while (tracking.contains(ticker));
/* Generate pseudo-random numbers using LCG algorithm as testing smaple. */
long x = 1;
for (int i = 0; i < values.length; i+=4) {
x = (a * x + c) % m;
values[i] = (byte)(x & 0xFF);
values[i+1] = (byte)((x>>8) & 0xFF);
values[i+2] = (byte)((x>>16) & 0xFF);
values[i+3] = (byte)((x>>24) & 0xFF);
}
/* Write generated numbers in a file. */
try(FileOutputStream output = (new FileOutputStream(ticker+".bin"))) {
output.write(values);
}
/* Runing Dieharder bundle. */
((new ProcessBuilder("dieharder", "-a", "-g", "201", "-f", ""+ticker+".bin").redirectOutput(new File(ticker+".log"))).start()).waitFor();
/* Delete binary sample file. */
(new File(ticker+".bin")).delete();
/* Keep trakcing of the checked constants. */
tracking.add(ticker);
Files.write(Paths.get("tracking.txt"), new ArrayList<>(tracking), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
}
}