首页
社区
课程
招聘
[原创]第七题 密室逃脱 WriteUp
发表于: 2018-6-29 12:06 3980

[原创]第七题 密室逃脱 WriteUp

2018-6-29 12:06
3980

这道题,逆向起来逻辑其实很简单,但是,难算……回去要好好学一学算法了……

程序的逻辑非常简单,程序将输入映射为0-63的数字,按确定的次序去查一个646464的三维数组,类似于M[a0][a1][a2] = b1这样的规律,顺序可以经过动态调试提取出来:

查完一轮以后,将这次的结果作为下一轮的输入,这样重复查20轮,最后和一个固定数组进行比较。

三维的表反查是比较困难的,因为每一个数字都出现了64*64次,而且输入中的一字节会和输出的三字节有关,同理输出相对输入也是一样。我首先的想法是暴力搜索,但是64^16的复杂度有点太高了。然后尝试数学拟合那个表的函数,搞了七八个小时都没搞出来……还是尝试搜索,发现可以剪枝,先找每一位出现的最后位置,再生成一个数组,表示确定这一位的搜索范围最多到多少,然后……暴力DFS……

在我的机器上大概20分钟算一组出来……
暴力出来最后需要的数字是

换算成字符得到Flag

虽然数学方法没有拟合出来,但是我推出了F(0, y, z)=a满足的关系式:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-6-29 12:07 被acdxvfsvd编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 1020
活跃值: (340)
能力值: ( LV12,RANK:306 )
在线值:
发帖
回帖
粉丝
2

const int st[16]={20,34,30,16,56,48,24,16,4,26,36,8,2,38,56,42};
const int u[16][3]={
{0,1,2},
{3,4,0},
{5,6,0},
{5,7,1},
{4,6,1},
{8,2,3},
{9,2,4},
{7,10,3},
{8,12,5},
{11,13,6},
{12,13,7},
{11,14,9},
{14,8,10},
{15,9,10},
{15,11,12},
{15,13,14}
};
const int n=64,m=16,v=3;

char o[64][64][64];
int lst[16],s[16],t[16],l[16],p[16];

inline bool dfs(int x)
{
       //out,"dfs:",x,'\n';
       if(x>1&&p[x-1]!=p[x-2])
       {
               fo(j,p[x-2],p[x-1]-1)
                       if(o[t[u[j][0]]][t[u[j][1]]][t[u[j][2]]]!=s[j])return 0;
       }
       if(x==m)
       {
               out,"ok\n";
               return 1;
       }
       fo0(i,n)
       {
               t[x]=i;
               if(dfs(x+1))return 1;
       }
       return 0;
}

int main()
{
       freopen("in.txt","r",stdin);
       fread(o,1,sizeof(o),stdin);
       fo0(i,n)fo0(j,n)fo0(k,n)assert(o[i][j][k]<n);
       fo0(i,m)s[i]=st[i];
       fo0(i,m)
       {
               l[i]=max(u[i][0],max(u[i][1],u[i][2]));
               if(i)repr(l[i],l[i-1]);
       }
       fo0(i,m)p[l[i]]=i+1;
       fo1(i,m-1)repr(p[i],p[i-1]);
       fo0(i,m)out,p[i],' ';out,'\n';
       //fo0(i,m)t[i]=rand()%64;
       //fo0(j,m)s[j]=o[t[u[j][0]]][t[u[j][1]]][t[u[j][2]]];
       fo0(i,m)out,s[i],' ';out,'\n';
       fo0(i,20)
       {
               out,i,"==========================\n";
               dfs(0);
               fo0(j,m)out,t[j],' ';out,'\n';
               fo0(j,m)assert(s[j]==o[t[u[j][0]]][t[u[j][1]]][t[u[j][2]]]);
               fo0(j,m)s[j]=t[j];
       }
       while(1);
}
2018-6-30 22:20
0
游客
登录 | 注册 方可回帖
返回
//