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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
""" R = final rand value S = merged state value s = original state value """ import random import sys N = 624 M = 397 MAX = 0xffffffff MOD = MAX + 1
STATE_MULT = 1812433253 STATE_MULT_INV = 2520285293 MT_RAND_MT19937 = 1 MT_RAND_PHP = 0
def php_mt_initialize(seed): """Creates the initial state array from a seed. """ state = [None] * N state[0] = seed & 0xffffffff; for i in range(1, N): r = state[i-1] state[i] = ( STATE_MULT * ( r ^ (r >> 30) ) + i ) & MAX return state
def _undo_php_mt_initialize(s, i): s = (STATE_MULT_INV * (s - i)) & MAX return s ^ s >> 30
def undo_php_mt_initialize(s, p): """From an initial state value `s` at position `p`, find out seed. """ for i in range(p, 0, -1): s = _undo_php_mt_initialize(s, i) return s
def php_mt_rand(s1): """Converts a merged state value `s1` into a random value, then sent to the user. """ s1 ^= (s1 >> 11) s1 ^= (s1 << 7) & 0x9d2c5680 s1 ^= (s1 << 15) & 0xefc60000 s1 ^= (s1 >> 18) return s
def undo_php_mt_rand(s1): """Retrieves the merged state value from the value sent to the user. """ s1 ^= (s1 >> 18) s1 ^= (s1 << 15) & 0xefc60000
s1 = undo_lshift_xor_mask(s1, 7, 0x9d2c5680)
s1 ^= s1 >> 11 s1 ^= s1 >> 22
return s1
def undo_lshift_xor_mask(v, shift, mask): """r s.t. v = r ^ ((r << shift) & mask) """ for i in range(shift, 32, shift): v ^= (bits(v, i - shift, shift) & bits(mask, i, shift)) << i return v
def bits(v, start, size): return lobits(v >> start, size) def lobits(v, b): return v & ((1 << b) - 1) def bit(v, b): return v & (1 << b) def bv(v, b): return bit(v, b) >> b
def php_mt_reload(state, flavour): s = state for i in range(0, N - M): s[i] = _twist_php(s[i+M], s[i], s[i+1], flavour) for i in range(N - M, N - 1): s[i] = _twist_php(s[i+M-N], s[i], s[i+1], flavour)
def _twist_php(m, u, v, flavour): """Emulates the `twist` and `twist_php` #defines. """ mask = 0x9908b0df if (u if flavour == MT_RAND_PHP else v) & 1 else 0 return m ^ (((u & 0x80000000) | (v & 0x7FFFFFFF)) >> 1) ^ mask
def undo_php_mt_reload(S000, S227, offset, flavour): X = S000 ^ S227
s22X_0 = bv(X, 31) if s22X_0: X ^= 0x9908b0df
s227_31 = bv(X, 30) if s227_31: X ^= 1 << 30
s228_1_30 = (X << 1) for s228_0 in range(2): for s228_31 in range(2): if flavour == MT_RAND_MT19937 and s22X_0 != s228_0: continue s228 = s228_0 | s228_31 << 31 | s228_1_30
s227 = _undo_php_mt_initialize(s228, 228) if flavour == MT_RAND_PHP and bv(s227, 0) != s22X_0: continue if bv(s227, 31) != s227_31: continue
rand = undo_php_mt_initialize(s228, 228) state = php_mt_initialize(rand) php_mt_reload(state, flavour)
if not S000 == state[0]: continue
return rand return None
def main(_R000, _R227, offset, flavour): _R000 <<= 1 _R227 <<= 1 for R000_0 in range(2): for R227_0 in range(2): R000 = _R000 | R000_0 R227 = _R227 | R227_0 S000 = undo_php_mt_rand(R000) S227 = undo_php_mt_rand(R227) seed = undo_php_mt_reload(S000, S227, offset, flavour) if seed: print(seed) return seed
def test_do_undo(do, undo): for i in range(10000): rand = random.randrange(1, MAX) done = do(rand) undone = undo(done) if not rand == undone: print(f"-- {i} ----") print(bin(rand).rjust(34)) print(bin(undone).rjust(34)) break
def test(): test_do_undo( php_mt_initialize, lambda s: undo_php_mt_initialize(s[227], 227) ) test_do_undo( php_mt_rand, undo_php_mt_rand ) exit()
import requests import json url = "https://twoshot.hgame.n3ko.co/" req = requests.session() r = req.get(url+"index.php") r = req.get(url+"random.php?times=228") data = json.loads(r.content) seed = main(data[0], data[len(data)-1], 0, 0) r = req.post(url+"verify.php", data={"ans":seed}) print(r.content)
|