地图种子的逆向研究

2024-11-08 14:10:37

1、 约定:  在本文中我们仅考虑了村庄的分布,事实上有一些其他结构的分布也是可以考虑的。  本系列文章中的Minecraft指的都是Minecraft Java Edition, 1.12.2。  本系列文章中引用的代码都来自 forge-1.12.2-14.23.2.2611-mdk。  当我们说”区块(x,z)“时,我们指的是chunk coordinate为(x,z)的区块。  我们将村庄中心所在的区块(也就是村里那口井所在的区块)称之为村庄区块。  猴子都知道的常识1:2^64的搜索空间对一般民用计算设备太大了。  猴子都知道的常识2:群系生成非常复杂。

地图种子的逆向研究

3、复制代码其中LINE_1处的this.world.setRandomSeed是一个与世界种子和当前区块位置相关的函数。如果将LINE_2注释掉,那么村庄生成就与群系无关,我们将这样修改过后会生成村庄的区块称之为拟村庄区块。则我们有显然的结论:村庄区块必然是拟村庄区块,但反之不对。

地图种子的逆向研究

5、 这个结论说明了两个问题:一,仅通过村庄位置是无法完全确定世界种子的;二、我们可以将首次爆破的搜索空间减少到2^48。三、上文中我们提到群系生成使用了MC自写的随机数生存器,它使用了世界种子的全部64bit,使得村庄区块相对于拟村庄区块所需搜索空间暴涨了2^16倍,也就是说直接通过村庄区块精确匹配的话,我们需要搜索整个int64范围,更不用说复杂的群系生成方**使单个搜索分支变慢多少了。  具体地说,我们首先通过跑图获得若干村庄区块(从而是拟村庄区块)的区块坐标(x_1,z_1),...,(x_n,...z_n) (这个n取多少读者自行决定,太多就会拖慢搜索速度,太少则会使通过的种子太多)。然后在0~2^48-1范围内搜索在(x_1,z_1),...,(x_n,...z_n) 这些位置是拟村庄区块的种子,得到若干备选项s_1,s_2,...,s_k(可能不止一个)。然后获得世界内某些位置的群系(当然,这种群系越稀少越好),再对每个n,计算以s_n+2^48*r( 1<=r<=2^16)为种子的地图内这些位置的群系是否与给定的群系吻合。通过这样两轮筛选,我们就能获得世界的种子了。

地图种子的逆向研究
猜你喜欢