encrypt
from hashlib import *
from itertools import *
from binascii import hexlify , unhexlify
from flag import flag ,seed
assert len(flag) == 26
assert flag[:7] == 'npuctf{'
assert flag[-1] == '}'
XOR = lambda s1 ,s2 : bytes([x1 ^ x2 for x1 ,x2 in zip(s1 , s2)])
class mt73991:
def __init__(self , seed):
self.state = [seed] + [0] * 232
self.flag = 0
self.srand()
self.generate()
def srand(self):
for i in range(232):
self.state[i+1] = 1812433253 * (self.state[i] ^ (self.state[i] >> 27)) - i
self.state[i+1] &= 0xffffffff
def generate(self):
for i in range(233):
y = (self.state[i] & 0x80000000) | (self.state[(i+1)%233] & 0x7fffffff)
temp = y >> 1
temp ^= self.state[(i + 130) % 233]
if y & 1:
temp ^= 0x9908f23f
self.state[i] = temp
def getramdanbits(self):
if self.flag == 233:
self.generate()
self.flag = 0
bits = self.Next(self.state[self.flag]).to_bytes(4 , 'big')
self.flag += 1
return bits
def Next(self , tmp):
tmp ^= (tmp >> 11)
tmp ^= (tmp << 7) & 0x9ddf4680
tmp ^= (tmp << 15) & 0xefc65400
tmp ^= (tmp >> 18) & 0x34adf670
return tmp
def encrypt(key , plain):
tmp = md5(plain).digest()
return hexlify(XOR(tmp , key))
if __name__ == "__main__":
flag = flag.encode()
random = mt73991(seed)
f = open('./cipher.txt' , 'wb')
for i in flag:
key = b''.join([random.getramdanbits() for _ in range(4)])
cipher = encrypt(key , chr(i).encode())
f.write(cipher)
decrypt
这是一道伪随机的题目,mt73991算法.题目并未给我们足够长的序列,也就是说不能逆向回去,因此想到可能要爆破,考虑到python的性能并不是很好,因此在c/c++中爆破较好(实际上计算机的好坏也影响很大).
首先先要逆向Next()函数.该函数是由一系列的移位异或运算得到的.(与运算用作掩码)
因此在每个式子中只需分段一段一段还原即可.
def reverse1(x):
x1=x[:18]
tmp=eval('0b'+x[:14])&(eval('0b'+bin(0x34adf670)[2:][-14: