详解W形状的栅栏密码

最近做密码学题目的时候碰到了一个特别的栅栏密码:加密后为:ccehgyaefnpeoobe{lcirg}epriec_ora_g,由题目得知密钥为5,在网上用普通的解码器只会得到一个令人黑人问号的字符串,在网上找题解的时候才知道这叫W形栅栏密码
话说我在网上搜资料的时候没有搜到太多与这有关的东西,本来想做一个不动脑子的伸手党。。。。现实却在逼迫我不得不去思考。。。。我这算第一个写这个的人不[手动滑稽]
在这里插入图片描述
如图,字符串“123456789”的密钥为3的话,就如上图所排列,然后得到密文:“159246837”。
然后该怎样去写一个解这样密码的程序呢,蒟蒻的我陷入了深深的思考。。。。

--------------------------------------------------------------很久很久之后--------------------------------------------
发现:当key=3时,一共分成了三行,打乱前的第一第五第九分别变成了打乱后的第一二三,这两个数之间相差4也就是(key-1)2,第key行与第一行相同,。再看第二行,难道是2n吗???我决定将数据放大再研究一番,当len=35,key=5时(这个就自己画一画吧)然后你就会发现:首行和尾行的间隔依旧不变,假设行数为i,当当前数为第2行的奇数的时候,下一个数字为2+6=8也就是(key-i)*2,若当前数为第二行偶数的时候,下一个数字为8+2=10也就是(i-1)*2。而且每一行的第一个数字就是这一行的行数。对不对?再用C++水个代码:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
char str[10000];
char ans[1000];
int line=0;
int key;
int len;
int sit;
int ssit;//用于判断当前字符的位置为奇数还是偶数
int check()//我刚才的思想
{
    if(line==1 ||line==key)return sit+(key-1)*2;
    else
    {
        if(ssit%2==1)return sit+(key-line)*2;
        else return sit+2*(line-1);
    }
}
int main()
{
    int i;
    cin>>str;
    scanf("%d",&key);
    len=strlen(str);
    for(i=len;i>0;i--)str[i]=str[i-1];//给他往前挪一位,方便操作。
    line=1;
    sit=1;
    ssit=1;

    for(i=1;i<=len;i++)//把密文按顺序安排到原来明文的位置上
    {
        ans[sit]=str[i];
        sit=check();查找下一个位置
        ssit++;
        if(sit>len)//超过长度了这个位置肯定不存在字符
        {
            line++;
            sit=line;//因为每一行第一个字符的位置恰好与行数的数字一样
            ssit=1;
        }
    }
    for(i=1;i<=len;i++)printf("%c",ans[i]);//cout<<ans;应该也行,没改
    return 0;
}

在这里插入图片描述
哼哼,谁也无法阻止我去找到密码!!!
あることを隠した。へへへ
はい、以上終わりました、ご覧くださってありがとうございます。
2019.10.1更新:
TMD我写这篇文章之前一个写代码的都没有,我这篇一出来再搜索W栅栏密码都更新了自己的脚本。F**k,就不能让我做个伸手党吗[手动滑稽]

发布了36 篇原创文章 · 获赞 29 · 访问量 3976

猜你喜欢

转载自blog.csdn.net/YUK_103/article/details/98163062