伪随机数生成器MT19937
-
做到相关的题目就直接来先学习一下。
-
参考博客:https://hasegawaazusa.github.io/mersenne-twister-note.html
-
参考博客:https://huangx607087.online/2021/07/10/Explore-MT19937/
-
参考博客:MT19937 分析 | Xenny 的博客,
Xenny
老师这篇将如何逆向MT19937讲的挺好的。
MT19937
- 对于
MT19937
的介绍,已经在前面的一篇文章中介绍过了,接下来就具体学习一下MT19937
具体的算法过程。 - 对于
MT19937
的应用,其实很多语言的random
这个库都使用的是MT19937
这个算法,比如python
、PHP
和Matlab
,并且从C++11
开始,C++
也可以使用梅森旋转算法(MT19937),对应的命名空间为std::mt19937_64
。 MT19937
这个伪随机数生成器,目前被视为最好的随机数算法。- 做个统一:以下文章中的内容都以
MT19937
来表示该算法。
MT19937原始版本
-
该版本其实就是使用
32
位的整数作为该算法的种子。之后的64
位是后来的一个变种版本,初学的时候一开始只要学原始版本即可。 -
接下来我们一步一步介绍一下
MT19937
的具体过程,采用的是该博客的方式:https://hasegawaazusa.github.io/mersenne-twister-note.html,先分布介绍,最后再将算法有个整体概念。 -
代码采用的是这篇博客的代码,实现的比较简洁:https://huangx607087.online/2021/07/10/Explore-MT19937/
-
这个算法其实总的来说有三个部分,分别就是
初始化操作
、获得伪随机数(提取伪随机数)
、梅森旋转操作
初始化
- 代码如下:
1 | # 由于Python中支持无限长度的整型,所以我们需要定义一个函数来实现32位整型的提取 |
- 这里主要就是利用用户传入的种子,对该
MT19937
中的初始状态寄存器做一个初始化操作,使得624
个初始化状态寄存器都有对应的值。
提取伪随机数
- 代码如下:
1 | def getbits(self): |
梅森旋转操作
- 代码如下:
1 | def twist(self): |
总体代码
1 | # 由于Python中支持无限长度的整型,所以我们需要定义一个函数来实现32位整型的提取 |
MT19937-64版本
MT19937破解
状态破解
矩阵状态破解
旋转破解
MT19937常见题型
- 这一部分主要是参考:https://huangx607087.online/2021/07/10/Explore-MT19937/
- 由于初始状态寄存器一共有
624*32=19968个bit位
,所以要恢复、预测等需要19968
个bit位,所以在MT19937
的题型都是围绕着已知bit
位来实现的。
题型1_预测随机数
- 给了足够多的数据后其实可以预测随机数的,并且有在Python中其实有现成的库可以使用,当然其实也可以自己逆向以下
MT19937
的算法,自己预测破解。
题目1_XYCTF2025_Division
题目2_
题型2_恢复随机数
- 这类题型其实就是选用一开始生成的随机数对
flag
等密文进行加密,之后给你后续一大堆随机数,让你恢复出随机数种子和初始状态寄存器 - 恢复出随机数种子和初始状态寄存器,从而可以得到一开始生成的随机数值,从而获得密钥,对
flag
的密文进行解密操作。
题目1_XYCTF2025_choice
题型3_给一定量任意的bit
- 这种情况是题目给你一定量
任意的伪随机数的bit
,从而让你恢复这个伪随机数。这种情况其实就是要进行一定量的操作了。 - 有些情况他会给你足够的
bit
也就是19968
个bit
或者超过19968个
bit,此时还是比较好恢复初始状态寄存器的。 - 但是有些情况题目不会给你足够数量的
bit
位,此时可能就需要对MT19937
的旋转过程或者其他过程进行破解。从而恢复初始状态寄存器。
题目1_Random game
题目2_never enough
相关库分析
python中random库
C++中std::mt19937_64
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 iyheart的博客!