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)
deftwist(self): for i inrange(0, 624): y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff)) self.mt[i] = (y >> 1) ^ self.mt[(i + 397) % 624]
if y % 2 != 0: self.mt[i] = self.mt[i] ^ 0x9908b0df
针对题目
1.逆向extract_number
我们发现这其中有两种操作是较难的,我们先来看这一种
1
y = y ^ y >> 11
显而易见,这种操作并不会对y的高18位有任何影响,所以y'=y ^ y >> 11的高18位就是y的高18位,而y'接下来的18位正是y的高18位和y接下来的18位异或得来的,所以我们可以使用已知的高18位得到接下来的18位,同上,每操作一次我们就可得到y的18位,所以我们就能利用y'通过有限的操作后复原之前的y,实现代码如下:
1 2 3 4 5 6
y1 = y = y1^y1>>11 for i inrange(32//11): y = y1^(y>>11) print(y) print(y1)