列变位法解密

来源:互联网 发布:linux 删除过期文件 编辑:程序博客网 时间:2024/05/16 07:28

列变位法解密

Accepts: 1211
Submissions: 4592
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description

列变位法是古典密码算法中变位加密的一种方法,具体过程如下 将明文字符分割成个数固定的分组(如5个一组,5即为密钥),按一组一行的次序整齐排列,最后不足一组不放置任何字符,完成后按列读取即成密文。

比如:

原文:123456789

密钥:4

变换后的矩阵:

123456789xxx

(最后的几个x表示无任何字符,不是空格,不是制表符,就没有任何字符,下同)

密文:159263748

再比如:

原文:Hello, welcome to my dream world!

密钥:7

变换后的矩阵:

Hello,welcome to my dream world!xx

密文:

Hw doeetrrlloellc adoomm!,my e w

实现一个利用列变位法的加密器对Bob来说轻而易举,可是,对Bob来说,想清楚如何写一个相应的解密器似乎有点困难,你能帮帮他吗?

Input

第一行一个整数T ,表示T 组数据。

每组数据包含2 

第一行,一个字符串s1|s|1e5 ,表示经过列变位法加密后的密文

第二行,一个整数K1K|s| ,表示原文在使用列变位法加密时的密钥

输入保证密文字符串中只含有ASCII码在[0x20,0x7F) 范围内的字符

Output

对于每组数据,先输出一行

Case #i:

然后输出一行,包含一个字符串s_decrypt,表示解密后得到的明文

Sample Input
41592637484Hw doeetrrlloellc adoomm!,my  e w7Toodming is best16sokaisan1
Sample Output
Case #1:123456789Case #2:Hello, welcome to my dream world!Case #3:Toodming is bestCase #4:sokaisan
这是一个模拟题,按照题目模拟即可,先竖着把字符存进去,然后在横着遍历,用结构体代替二维数组,不然会有数组越界的可能,代码如下:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<set>using namespace std;struct node{    int x;    char y;}b[100000];int main(){    int t,uuu;    int tt=1;    scanf("%d",&t);    getchar();    while(t--)    {        char a[101000];        gets(a);        int key;        scanf("%d",&key);        getchar();        printf("Case #%d:\n",tt++);        int l =strlen (a);        if(l==key||l==1)        {            puts(a);            continue;        }        int j=0,f=0;        int u;        if(l%key==0)            u=l/key;        else            u=l/key+1;        int mm=u;        for(int i=0; ; i++)        {            b[i].x=f;            b[i].y=a[i];            f++;            if(f==u)            {//对已知的数进行编号,清楚它在哪一列                key--;                if(key==0)                   {                    uuu=i+1;                       break;                   }                l=l-u;                if(l%key==0)                    u=l/key;                else                    u=l/key+1;                f=0;            }        }        for(int i=0; i<mm; i++)            for(int j=0; j<uuu; j++)            {               //遍历,依次输出第零列至第mm-1列;                if(b[j].x==i)                printf("%c",b[j].y);            }        printf("\n");    }}


0 0
原创粉丝点击