commit c85b8ec790b77ce7c6ddbbab0849e00ec707b10c
parent 91cd6a94aa2449837cab04623b06cf216f1d08f4
Author: mpizzzle <michael.770211@gmail.com>
Date: Sat, 16 Feb 2019 17:30:33 +0000
holy shit it works, challenge 23 complete
Diffstat:
1 file changed, 52 insertions(+), 48 deletions(-)
diff --git a/set3/clone_mt_rng_state.py b/set3/clone_mt_rng_state.py
@@ -1,9 +1,8 @@
def _int32(x):
# Get the 32 least significant bits.
- return int(0xFFFFFFFF & x)
+ return int(0xffffffff & x)
class MT19937:
-
def __init__(self, seed):
# Initialize the index to 0
self.index = 624
@@ -12,6 +11,9 @@ class MT19937:
for i in range(1, 624):
self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)
+ def set_state(self, cloned_state):
+ self.mt = cloned_state
+
def extract_number(self):
if self.index >= 624:
self.twist()
@@ -35,59 +37,61 @@ class MT19937:
for i in range(624):
# Get the most significant bit and add it to the less significant
# bits of the next number
- y = _int32((self.mt[i] & 0x80000000) +
- (self.mt[(i + 1) % 624] & 0x7fffffff))
+ y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff))
self.mt[i] = self.mt[(i + 397) % 624] ^ y >> 1
if y % 2 != 0:
self.mt[i] = self.mt[i] ^ 0x9908b0df
self.index = 0
-def test_temper(yy):
- y = _int32(yy)
- y = y ^ y >> 11
- #y = y ^ y << 7 & 2636928640
- #y = y ^ y << 15 & 4022730752
- y = y ^ y >> 18
- return _int32(y)
-
+#todo: rewrite this function now you have a better grasp on it.
def untemper_11(yy):
- y = _int32(yy)
- print format(y, '#034b')
- temp1 = y >> (32 - 11)
- print format(temp1, '#034b')
- temp2 = (y & 0x1fffff) >> (32 - 11 - 11)
- print format(temp2, '#034b')
- temp3 = temp1 ^ temp2# >> 1
- print format(temp3, '#034b')
- temp4 = int(str(format(temp1, '#011b')) + str(format(temp3, '011b')), 2) >> 1
- print format(temp4, '#034b')
- temp5 = temp4 ^ y
- print format(temp5, '#034b')
- return _int32(temp5)
+ y = _int32(yy)
+ temp1 = y >> (32 - 11)
+ temp2 = (y & 0x1fffff) >> (32 - 11 - 11)
+ temp3 = temp1 ^ temp2
+ temp4 = int(str(format(temp1, '#011b')) + str(format(temp3, '011b')), 2) >> 1
+ temp5 = temp4 ^ y
+ return _int32(temp5)
+
+def untemper_7(yy):
+ y = yy ^ (((yy & 0x7f) << 7) & 2636928640)
+ y = yy ^ (((y & 0x3fff) << 7) & 2636928640)
+ y = yy ^ (((y & 0x1fffff) << 7) & 2636928640)
+ y = yy ^ (((y & 0xfffffff) << 7) & 2636928640)
+ y = yy ^ (((y & 0xffffffff) << 7) & 2636928640)
+
+ return _int32(y)
+
+def untemper_15(yy):
+ y = yy ^ (((yy & 0x7fff) << 15) & 4022730752)
+ y = yy ^ (((y & 0x3fffffff) << 15) & 4022730752)
+ y = yy ^ (((y & 0xffffffff) << 15) & 4022730752)
+
+ return _int32(y)
def untemper_18(yy):
- y = _int32(yy)
- print format(y, '#034b')
- temp1 = y >> (32 - 11)
- print format(temp1, '#034b')
- temp2 = (y & 0x1fffff) >> (32 - 11 - 11)
- print format(temp2, '#034b')
- temp3 = temp1 ^ temp2# >> 1
- print format(temp3, '#034b')
- temp4 = int(str(format(temp1, '#011b')) + str(format(temp3, '011b')), 2) >> 1
- print format(temp4, '#034b')
- temp5 = temp4 ^ y
- print format(temp5, '#034b')
- return _int32(temp5)
-
-def test_untemper(yy):
- y = _int32(yy)
- y = untemper_18(y)
- #y = y ^ y << 15 & 4022730752
- #y = y ^ y << 7 & 2636928640
- y = untemper_11(y)
- return _int32(y)
+ return _int32(yy ^ yy >> 18)
+
+def untemper(yy):
+ y = _int32(yy)
+ y = untemper_18(y)
+ y = untemper_15(y)
+ y = untemper_7(y)
+ y = untemper_11(y)
+ return _int32(y)
+
+unknown_seed = 12668778
+mt = MT19937(unknown_seed)
+
+cloned_mt_state = [0] * 624
+
+for i in range(624):
+ cloned_mt_state[i] = untemper(mt.extract_number())
+
+cloned_mt = MT19937(0)
+cloned_mt.set_state(cloned_mt_state)
-print _int32(48762549)
-print _int32(48762549) == test_untemper(test_temper(48762549))
+print mt.extract_number()
+print cloned_mt.extract_number()
+print mt.extract_number() == cloned_mt.extract_number()