import
java.util.Arrays;
import
java.util.Random;
import
javax.sql.RowSetEvent;
import
javax.sql.RowSetListener;
import
javax.sql.rowset.JdbcRowSet;
import
javax.sql.rowset.RowSetProvider;
class
GFG {
private
static
long
SEED = 782634283105L;
private
static
int
NUM_GEN =
5
;
private
static
int
[] genNum(
long
seed)
{
Random rand =
new
Random(seed);
int
arr[] =
new
int
[NUM_GEN];
for
(
int
i =
0
; i < arr.length; i++) {
arr[i] = rand.nextInt();
}
return
arr;
}
public
static
void
main(String args[])
{
int
arr[] = genNum(SEED);
System.out.println(Arrays.toString(arr));
Long result = reverse(arr);
if
(result !=
null
) {
System.out.println(
Arrays.toString(genNum(result)));
}
else
{
System.out.println(
"Seed not found"
);
}
}
private
static
long
combine(
int
rand,
int
suffix)
{
return
(unsignedIntToLong(rand) <<
16
)
| (suffix & ((1L <<
16
) -
1
));
}
private
static
long
unsignedIntToLong(
int
num)
{
return
num & ((1L <<
32
) -
1
);
}
private
static
Long reverse(
int
arr[])
{
assert
(arr.length >
1
);
int
end = arr.length -
1
;
for
(
int
i =
0
; i < (
1
<<
16
); i++) {
long
candidateSeed = combine(arr[end], i);
long
previousSeed
= getPreviousSeed(candidateSeed);
if
((previousSeed >>>
16
)
== unsignedIntToLong(arr[end -
1
])) {
System.out.println(
"Testing seed: "
+ previousSeed +
" --> "
+ candidateSeed);
for
(
int
j = end -
1
; j >=
0
; j--) {
candidateSeed = previousSeed;
previousSeed
= getPreviousSeed(candidateSeed);
if
(j >
0
&& (previousSeed >>>
16
)
== unsignedIntToLong(
arr[j -
1
])) {
System.out.println(
"Verifying: "
+ previousSeed
+
" --> "
+ candidateSeed);
}
else
if
(j ==
0
) {
System.out.println(
"Seed found: "
+ (previousSeed ^ MULTIPLIER));
return
previousSeed ^ MULTIPLIER;
}
else
{
System.out.println(
"Failed"
);
break
;
}
}
}
}
return
null
;
}
private
static
long
ADDEND = 0xBL;
private
static
long
MULTIPLIER = 0x5DEECE66DL;
private
static
long
getPreviousSeed(
long
currentSeed)
{
long
seed = currentSeed;
seed -= ADDEND;
long
result =
0
;
for
(
int
i =
0
; i <
48
; i++) {
long
mask = 1L << i;
long
bit = seed & mask;
result |= bit;
if
(bit == mask) {
seed -= MULTIPLIER << i;
}
}
return
result & ((1L <<
48
) -
1
);
}
}