IDF-CTF-牛刀小试-聪明的小羊

题目:
一只小羊跳过了栅栏,两只小羊跳过了栅栏,一坨小羊跳过了栅栏…

tn c0afsiwal kes,hwit1r g,npt ttessfu}ua u hmqik e {m, n huiouosarwCniibecesnren.

分析:
看到栅栏。。。栅栏。。。栅栏。。。,所以想到用到的是栅栏密码。百度一下栅栏密码,在百科里面了解到一般是二栏栅栏,很显然这里不是。那么就是多栏栅栏了,那么到底是多少栏呢?
一般来说,解密过程是先把空格去掉的,然后再按固定分组来还原。我发现删去所有空格之后字符串长度为71,这是一个素数,不可以分解;再仔细看一下字符串,发现有些字符之间是有两个空格的,所以我就想空格是不可以忽略的,那么此时的字符串是85。85=17*5,那么我就可以猜想这里有两种情况,情况一:5个字符一栏;情况二:17个字符一栏。
我就先挑情况二来实现下(人比较懒,不想分那么多组)。
分了5组,分别如下:
1)tn c0afsiwal kes,
2)hwit1r g,npt tt
3)essfu}ua u hmqik
4) e {m, n huiouos
5)arwCniibecesnren.
然后从上到下合并起来就是:
the anwser is wctf{C01umnar},if u is a big new,u can help us think more question,tks.
好吧,这就是把密码还原了。
所以答案就是wctf{C01umnar}
试一下5个一组的情况吧。
5个一组解密的结果是taastg su km uwbnnfl,1, sah ,hoCer s hrntf me usncecikw ptuuq iaien0wei te} i{noris.
很明显是错误的。
我解题的时候用c++实现了解密过程,定义了一个5行17列的字符数组来存放分组。
代码如下:

#include <iostream>
#include<string>
#include<fstream>
using namespace std;

int main()
{
    char s[18][18];    //定义一个二维数组来存放字符分组
    int i,j,k;
    k=0;
    string s1,s2;
    s2="";
    s1="tn c0afsiwal kes,hwit1r g,npt ttessfu}ua u hmqik e {m, n huiouosarwCniibecesnren.";
    //cout<<s1.size(); 查看字符串的长度

    for(i=0;i<5;i++)          //5行17列
        for(j=0;j<17;j++)        //每17个字符一组(空格也算字符)
            s[i][j]=s1[k++];   //建立了5个分组,85=17*5

    for(i=0;i<5;i++)         //解密
        for(j=0;j<17;j++)
            s2=s2+s[j][i];

    cout<<s2;                     //结果
    ofstream out("e:\\test.txt");
    out<<s2;
    return 0;
}

此题让我困惑的是它要把空格也算上,因为一般情况下是要忽略空格的。
收获:让我了解了什么是栅栏密码。

你可能感兴趣的:(c,密码,idf)