Crypto 题。
作为一个萌新做过的最难的密码(
下载文件打开得到这个。
不妨先观察一下 hint,显然 hint 是某种从来没见过的编码。在百度搜索“不会吧就这”等词语可以发现 B 站的一个视频,他告诉我们存在一种阴阳怪气编码。
于是我把他的链接偷了下来:Here。
打开后把我们的一大堆 hint 粘贴进去得到:
他告诉我们要把 Cipher 拿去解一小会儿。
观察 Cipher 发现密码符合 base58 形式所以我们拖去 base58 解密得到:
然后编写程序给他加上若干 %
得到字符串 %4C%4A%4C%54%49%34%33%42%4B%52%4C%47%57%54%32%49%4F%51%59%57%45%33%54%45%4D%5A%4D%56%4F%55%4C%59%4C%41%5A%46%53%36%4B%59%47%4E%42%47%34%57%44%32%4E%42%58%46%55%56%32%47%48%45%3D%3D%3D%3D%3D%3D
,拖去 url 解密(别人的这一步貌似都是 base16。):
等号很多,不是 base64,所以是 base32:
接下来经过若干尝试,我们发现 base64 可以解码这个东西,而且形式已经相当接近答案:
由于很接近答案的有两个大括号的形式,我们猜测这就是最后一步,开始观察 alp。
alp 里面有一个特色就是字母和数字都没有重复,但是这个 alp 缺失了四个字母 a,g,v,r
,所以我们用这四个全排列替换 alp 中的 ?
再拿去解密。
仿射密码,是一种位移密码,工作原理百度百科写了,方程照着抄到代码里就行。
编写代码如下:
#include<bits/stdc++.h>
#define int long long
#define mid ((l+r)>>1)
#define fir first
#define sec second
#define lowbit(i) (i&(-i))
using namespace std;
const int N=5e5+5;
const int inf=1e18;
struct edge{int to,nxt,l;};
inline int read(){
char op=getchar();
int w=0,s=1;
while(op<'0'||op>'9'){
if(op=='-') s=-1;
op=getchar();
}
while(op>='0'&&op<='9'){
w=(w<<1)+(w<<3)+op-'0';
op=getchar();
}
return w*s;
}
map<char,bool> used;
char alp[N],pas[N],Try[N],ans[N];
//alp : slbn7q6u0w2pf3m9tzjx8o51yke????dhc4i
//pas : en,i5d8{unw_ad1_f2_pg_8gea}
//Input
/*
slbn7q6u0w2pf3m9tzjx8o51yke????dhc4i
en,i5d8{unw_ad1_f2_pg_8gea}
*/
void check(){
int cnt=0,m=strlen(alp+1);
map<char,int> f;
map<int,char> invf;
for(register int i=1;i<=m;i++){
f[alp[i]]=cnt;
invf[cnt]=alp[i];
cnt++;
}
int n=strlen(pas+1);
for(register int k=1;k<=35;k++){
for(register int b=0;b<=35;b++){
for(register int i=1;i<=n;i++){
if((pas[i]>'z'||pas[i]<'a')&&(pas[i]>'9'||pas[i]<'0')){
ans[i]=pas[i];
continue;
}
char opt=((f[pas[i]]+b)*k+36)%36;
ans[i]=invf[opt];
}
if(ans[4]=='f'&&ans[5]=='l'&&ans[6]=='a'&&ans[7]=='g'){
printf("k=%lld b=%lld ???? = %c%c%c%c : %s",k,b,Try[1],Try[2],Try[3],Try[4],ans+1);
exit(0);
}
}
}
}
void dfs(int x){
if(x==5){
for(register int i=28;i<=31;i++) alp[i]=Try[i-27];
check();
return;
}
if(used['a']==false){
Try[x]='a';
used['a']=true;
dfs(x+1);
Try[x]=0;
used['a']=false;
}
if(used['g']==false){
Try[x]='g';
used['g']=true;
dfs(x+1);
Try[x]=0;
used['g']=false;
}
if(used['v']==false){
Try[x]='v';
used['v']=true;
dfs(x+1);
Try[x]=0;
used['v']=false;
}
if(used['r']==false){
Try[x]='r';
used['r']=true;
dfs(x+1);
Try[x]=0;
used['r']=false;
}
}
signed main(){
scanf("%s",alp+1);
scanf("%s",pas+1);
dfs(1);
}
结果:
提交结果 flag{the_day_13_s0_g0od}
正确,终。
总结学到了一种新密码。挺浪费时间的。