ECNA2013 C . Playing Fair with Cryptography (模拟)

简介: ECNA2013 C . Playing Fair with Cryptography (模拟)

题目描述

Encryption is the process of taking plaintext and producing the corresponding ciphertext. One method to do this is the Playfair cipher. This cipher was invented by (who else) Charles Wheatstone in the 1850’s (but got its name from one of its most ardent promoters, the Scottish scientist Lyon Playfair). Unlike many substitution ciphers, the Playfair cipher does not encrypt single letters at a time, but groups of two letters called digraphs. The encryption process uses a 5 × 5 grid generated by a secret key known only to the two parties using the cipher (hopefully). The grid is generated as follows: You write the letters of the key, one letter per square row-wise in the grid starting at the top. Any repeated letters in the key are skipped. After this is done, the remaining unused letters in the alphabet are placed in order in the remaining squares, with I and J sharing the same square. For example, if the key was “ECNA PROGRAMMING CONTEST”, the generated square would look like the following:

20200401134307494.png

You encrypt a digraph using the following rules:


If both letters are in the same row, replace each with the letter to its immediate right (wrapping around at the end). For example, using the above grid the plaintext digraph DS is encrypted as FB, and AP is encrypted as PE.

If both letters are in the same column, replace each with the letter immediately below it (again wrapping around at the bottom). For example, PF is encrypted as IU (or JU), and WO is encrypted as CS.

Otherwise, “slide” the first character across its row until it is in the same column as the second character, and do the same for the second character. The two characters you end up on are the encrypted characters of the digraph. If you view the original digraph as corners of a rectangle in the grid, you are replacing them with the characters in the other two corners. For example, TU is encrypted as FH, UT is encrypted as HF, and ZC is encrypted as WP.

What happens when the digraph contains the same letter twice? In the original Playfair cipher you insert the letter ‘X’ between the two letters and continue encrypting. You also use an extra ‘X’ at the end of the plaintext if you have an odd number of letters. Thus the plaintext “OOPS” would first be changed to the digraphs “OX”, “OP” and “SX” and then would be encrypted as “GWICBW” (using the grid above). Note that the plaintext “POOS” would not need any added letters since the two ‘O’s do not appear in the same digraph.


We’ll modify the Playfair cipher in one simple way: Instead of always using ‘X’ as the inserted letter, use ‘A’ the first time an insertion is needed, then ‘B’ the next time, and so on (though you should never use ‘J’ as an inserted letter; just go from ‘I’ to ‘K’). Once you hit ‘Z’, you go back to using ‘A’. If the inserted letter would result in a digraph with the same two letters, you just skip to the next inserted letter. For example, “OOPS” would now become the digraph stream “OA”, “OP”, “SB” before being encrypted, and the plaintext “AABCC” would become the digraph stream “AB”, “AB”, “CD”, “CE”.


Given a key and plaintext, you are to generate the corresponding ciphertext.


输入描述

The input file will start with an integer n indicating the number of problem instances. Each instance consists of two lines, the first containing the key and the second the plaintext to encrypt. Both of these may contain upper- and lower-case letters, as well as spaces and non-alphabetic characters (both of which should be ignored). For simplicity, the letters ‘j’ and ’J’ will never appear in any key or plaintext.


输出描述

For each problem instance, output the case number followed by the corresponding ciphertext using upper-case letters with no space. Always use the letter ‘I’ instead of ‘J’ in the ciphertext


1

ECNA Programming Contest 2013

This is the easy problem!


Case 1: HVOFOFHVCPCPDWEIGSHNGD

题意

给出字符串s,t,用字符串s构造加密矩阵,求出字符串t的密文。

题目定义了一种加密方式:

首先构造加密矩阵,先遍历字符串s,依次将不在矩阵里的字符放置在矩阵里;然后将26个字母里还没有被放置在矩阵里的字符依次放在矩阵里。

然后加密的时候是每次都对两个字符进行操作,如果两个字符在同一行,都变为右侧的字母(循环的,一直在同一行);如果两个字符在同一列,都变为下册的字母(循环的,一直在同一列);否则,将其变为对角线的两个字母。

如果两个字母相同的话,就从A开始不断地插入。

注意:J应当始终被跳过。

思路

题目里处理的是大写字母,所以先对字符串进行处理,去掉多余字符,将小写字母变为大写字母。

首先应当构造出加密矩阵a,记录每个字母在加密矩阵里对应在第几行和第几列,分别为tx,ty。然后开始进行加密,每次都取两个字母。

如果当前字符等于下一个字符,那么就加密当前字母和新插入的字母;

如果只剩一个字符,加密当前字符和新插入的字符;

其他情况,加密当前字符和下一个字符。

代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
char a[10][10];
int b[27];
int tx[27],ty[27];
char getNext(char ch,int &idx){
  if(idx==ch-'A') idx=(idx+1)%26;
  if(idx==9) idx++;
  ch=idx+'A';
  idx=(idx+1)%26;
  if(idx==9) idx++;
  return ch;
}
void cul(char u,char v,char &x,char &y){
  int tu=u-'A',tv=v-'A';
  if(tx[tu]==tx[tv]){
    //cout<<"1"<<endl;
    //cout<<tu<<" "<<tx[tu]<<" "<<ty[tu]<<endl;
    //cout<<tv<<" "<<tx[tv]<<" "<<ty[tv]<<endl;
    //cout<<(ty[tu]+1)%5<<"***"<<(ty[tv]+1)%5<<endl;
    x=a[tx[tu]][(ty[tu]+1)%5];
    y=a[tx[tv]][(ty[tv]+1)%5];
    //cout<<x<<" "<<y<<endl;
  }else if(ty[tu]==ty[tv]){
    //cout<<"2"<<endl;
    x=a[(tx[tu]+1)%5][ty[tu]];
    y=a[(tx[tv]+1)%5][ty[tv]];
  }else{
    //cout<<"3"<<endl;
    x=a[tx[tu]][ty[tv]];
    y=a[tx[tv]][ty[tu]];
  }
}
int main(){
    int _,Case=1;cin>>_;
    while(_--){
      string ss,s="",t="",tt;
      if(Case==1) getchar();
      getline(cin,ss);
      getline(cin,tt);
    //  cout<<ss<<endl;
    //  cout<<tt<<endl;
      for(int i=0;i<ss.size();i++){
        if(ss[i]>='a'&&ss[i]<='z'){
          s+=ss[i]-'a'+'A';
      }
      else if(ss[i]>='A'&&ss[i]<='Z'){
        s+=ss[i];
      }
    }
    for(int i=0;i<tt.size();i++){
      if(tt[i]=='J') tt[i]='I';
      if(tt[i]>='a'&&tt[i]<='z') t+=tt[i]-'a'+'A';
      else if(tt[i]>='A'&&tt[i]<='Z') t+=tt[i];
    }
    //cout<<s<<endl;
    //cout<<t<<endl;
      int idx=0;
      memset(b,0,sizeof b);
      b[9]=1;
      for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)
          a[i][j]='*';
    for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
          while(b[s[idx]-'A']&&idx<s.size()) idx++;
          if(idx<s.size()){
            a[i][j]=s[idx],b[s[idx]-'A']=1;
        }
        else break;
      }
    }
    idx=0;
    for(int i=0;i<5;i++)
      for(int j=0;j<5;j++){
        if(a[i][j]!='*') continue;
        while(b[idx]) idx++;
        a[i][j]=idx+'A';
        b[idx]=1;
      }
    for(int i=0;i<5;i++){
      for(int j=0;j<5;j++){
        //cout<<a[i][j]<<" ";
        tx[a[i][j]-'A']=i;
        ty[a[i][j]-'A']=j;
      }
      //cout<<"\n";
    }
    idx=0;
    char x,y;
    string ans="";
    for(int i=0;i<t.size();i+=2){
      if(t[i]==t[i+1]){
        cul(t[i],getNext(t[i],idx),x,y);
        i--;
      }
      else if(i+2>t.size()){
        cul(t[i],getNext(t[i],idx),x,y);
      }
      else cul(t[i],t[i+1],x,y);
      ans=ans+x+y;
    }
    cout<<"Case "<<Case++<<": "<<ans<<endl;
  }
    return 0;
}


目录
相关文章
|
10月前
|
数据挖掘
MUSIED: A Benchmark for Event Detection from Multi-Source Heterogeneous Informal Texts 论文解读
事件检测(ED)从非结构化文本中识别和分类事件触发词,作为信息抽取的基本任务。尽管在过去几年中取得了显著进展
46 0
|
机器学习/深度学习 算法 图形学
Deep learning based multi-scale channel compression feature surface defect detection system
简述:首先应用背景分割和模板匹配技术来定义覆盖目标工件的ROI区域。提取的感兴趣区域被均匀地裁剪成若干个图像块,每个块被送到基于CNN的模型,以分类杂乱背景中不同大小的表面缺陷。最后,对空间上相邻且具有相同类别标签的图像块进行合并,以生成各种表面缺陷的识别图。
112 0
|
机器学习/深度学习 PyTorch 算法框架/工具
【多任务学习】Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics
【多任务学习】Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics
702 0
【多任务学习】Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics
《Towards A Fault-Tolerant Speaker Verification System A Regularization Approach To Reduce The Condition Number》电子版地址
Towards A Fault-Tolerant Speaker Verification System: A Regularization Approach To Reduce The Condition Number
68 0
《Towards A Fault-Tolerant Speaker Verification System A Regularization Approach To Reduce The Condition Number》电子版地址
|
自然语言处理
Re26:读论文 Don’t Stop Pretraining: Adapt Language Models to Domains and Tasks
Re26:读论文 Don’t Stop Pretraining: Adapt Language Models to Domains and Tasks
Re26:读论文 Don’t Stop Pretraining: Adapt Language Models to Domains and Tasks
|
数据安全/隐私保护
HDOJ 1048 The Hardest Problem Ever(加密解密类)
HDOJ 1048 The Hardest Problem Ever(加密解密类)
79 0
|
算法 Java 程序员
《Model Checking TLA+ Specifications》
《Model Checking TLA+ Specifications》
|
语音技术 机器学习/深度学习 开发者
语音顶会Interspeech 论文解读|Towards A Fault-tolerant Speaker Verification System: A Regularization Approach To Reduce The Condition Number
Interspeech是世界上规模最大,最全面的顶级语音领域会议,本文为Siqi Zheng, Gang Liu, Hongbin Suo, Yun Lei的入选论文
语音顶会Interspeech 论文解读|Towards A Fault-tolerant Speaker Verification System: A Regularization Approach To Reduce The Condition Number
|
机器学习/深度学习 算法
强化学习:Policy-based方法Part2
在本文中,将首先从数学角度对相关理论知识给出解答,并给出基于TensorFlow的实现过程。
1933 0
|
机器学习/深度学习
强化学习:Policy-based方法 Part 1
在前面两篇文章中,我们完成了基于值的(value-based)强化学习算法,可以在给定的环境下选择相应动作,并根据最高的Q-value来确定下一步的动作(最大化未来奖励期望)。可以看到,策略主要来源于对动作价值的估计过程。
4320 0

热门文章

最新文章