# 提取伪随机数 defextract_number(self): if self.mti == 0: self.twist() y = self.mt[self.mti] y = y ^ y >> 11 y = y ^ y << 7 & 2636928640 y = y ^ y << 15 & 4022730752 y = y ^ y >> 18 self.mti = (self.mti + 1) % 624 return _int32(y)
defconstruct_a_row(RNG): row = [] for _ inrange(19968//32): tmp = RNG.getrandbits(32) row += list(map(int, bin(tmp)[2:].zfill(32))) return row # 构造线性方程组的矩阵 L = [] for i in trange(19968): state = [0]*624# MT19937使用624个32位整数作为状态 # 构造一个只有一位为1,其他都为0的序列 temp = "0"*i + "1"*1 + "0"*(19968-1-i) # 将这个序列分成624段,每段32位,转换为整数 for j inrange(624): state[j] = int(temp[32*j:32*j+32], 2) RNG = Random() RNG.setstate((3,tuple(state+[624]),None)) L.append(construct_a_row(RNG)) # 将L转换为GF(2)上的矩阵(二进制域) L = Matrix(GF(2),L) print(L.nrows(), L.ncols()) defMT19937_re(state): try: # 构造目标向量R R = [] for i in state: R += list(map(int, bin(i)[2:].zfill(32))) R = vector(GF(2), R) s = L.solve_left(R) # 这里可能会抛出异常 # 将解转换为二进制字符串 init = "".join(list(map(str,s))) state = [] # 将解重新分割成624个32位整数 for i inrange(624): state.append(int(init[32*i:32*i+32],2)) # 创建新的RNG并设置恢复出的状态 RNG1 = Random() RNG1.setstate((3,tuple(state+[624]),None)) return RNG1 except Exception as e: print(f"[-]{e}") pass RNG = MT19937_re()
不过还是得根据具体情况来分析。不过这种方法在构造矩阵时花的时间其实挺长的,试了一下差不多得十分钟。
2,直接使用randcrack库进行预测
无脑调用库就行(bushi
1 2 3 4 5 6 7 8
import random #导入random库(Python内置了) from randcrack import RandCrack #你可以掷随机数种子来确保预测的有效性, 不过random预测的时候默认以当前时间作为随机数种子 rc = RandCrack()#实例化randcrack类 for i inrange(624):#循环624次 rc.submit(random.getrandbits(32))#每次循环提交一个32位random生成的随机数 print(random.getrandbits(64))#利用random库获取一个64位的随机数(你可以修改为任意位数) print(rc.predict_getrandbits(64))#利用randcrack获取的随机数
from gf2bv import LinearSystem from gf2bv.crypto.mt import MT19937 from tqdm import * import random from Crypto.Util.number import * defmt19937(bs, out): lin = LinearSystem([32] * 624) mt = lin.gens()
rng = MT19937(mt) #rng.getrandbits(175) zeros = [rng.getrandbits(bs) ^ o for o in out] + [mt[0] ^ 0x80000000] print("solving...")
sol = lin.solve_one(zeros)
rng = MT19937(sol) pyrand = rng.to_python_random() for i inrange(2496): out.append(pyrand.getrandbits(8)) print(pyrand.getrandbits(8)) import random random.seed(1) out=[] for i inrange(2496): out.append(random.getrandbits(8)) mt19937(8, out)