中国海洋大学第四届朗讯杯高级组 Playing Fair with Cryptography

本文介绍了一种基于Playfair密码的变体加密方法,并通过示例详细解释了其加密过程。该方法不仅保留了原始Playfair密码的基本原理,还引入了新的字母插入规则来增强加密效果。

Playing Fair with Cryptography

Time Limit: 1000MS    Memory limit: 65536K

题目描述

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 wasECNA PROGRAMMING CONTEST", the generated square would look like the following:
                                                        

You encrypt a digraph using the following rules:

1. 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.

2. 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.

3. Otherwise, slidethe 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 Xbetween 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 twoOs do not appear in the same digraph.

We\'ll modify the Playfair cipher in one simple way: Instead of always using Xas the inserted letter, useAthe first time an insertion is needed, then \'B\' the next time, and so on (though you should never use Jas 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, OOPSwould now become the digraph streamOA, OP, SBbefore being encrypted, and the plaintext AABCCwould become the digraph stream ABAB, 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

提示

来源

中国海洋大学第四届朗讯杯高级组

 

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2720&cid=1203

这个题其实挺水的,但是一些转化方面的细节我处理的不好WA了好多次。

另外注意和J有关的都要跳过。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#define MAXN 10005
#define INF 2139062143
#define inf -2139062144
#define ll long long
using namespace std;
map<char,int> mp1;
map<int,char> mp2;
void Convers(char a,char b,char &aa,char &bb)
{
    if(a=='J') a='I';
    if(b=='J') b='I';
    int x=mp1[a],y=mp1[b];
    if((x-1)/5==(y-1)/5) //同行
    {
        int xx=x+1,yy=y+1;
        if((xx-1)/5>(x-1)/5) xx=xx-5;
        if((yy-1)/5>(y-1)/5) yy=yy-5;
        aa=mp2[xx];
        bb=mp2[yy];
        return ;
    }
    if((x-1)%5==(y-1)%5) //同列
    {
        int xx=x+5,yy=y+5;
        if((xx-1)/5>=5) xx=(x-1)%5+1;
        if((yy-1)/5>=5) yy=(y-1)%5+1;
        aa=mp2[xx];
        bb=mp2[yy];
        return ;
    }
   int xx=(x-1)/5*5+(y-1)%5+1,yy=(y-1)/5*5+(x-1)%5+1;
   aa=mp2[xx];
   bb=mp2[yy];
}
int main()
{
    int T,kase=0;
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        mp1.clear();
        mp2.clear();
        char s1[MAXN]={0},s2[MAXN]={0};
        gets(s1);
        gets(s2);
        int flag=0;
        for(int i=0; s1[i]; ++i)
        {
            if(isalpha(s1[i]))
            {
                char t=toupper(s1[i]);
                if(!mp1[t])
                {
                    ++flag;
                    mp1[t]=flag;
                    mp2[flag]=t;
                }
            }
        }
        for(int i=0; i<26; ++i)
        {
            char t='A'+i;
            if(t=='J') continue;
            if(!mp1[t])
            {
                ++flag;
                mp1[t]=flag;
                mp2[flag]=t;
            }
        }
        mp1['J']=mp1['I'];
        char str[MAXN]= {0};
        int len=0;
        for(int i=0; s2[i]; ++i)
            if(isalpha(s2[i]))
            {
                char t=toupper(s2[i]);
                str[len++]=t;
            }
        str[len]=0;
        int use=0;
        char ans[MAXN]= {0};
        int l=0;
        char aa,bb;
        for(int i=0; i<len;)
        {
            use=use%26;
            if(i==len-1)
            {
                while((use%26)+'A'==str[i]||((use%26)+'A'=='J')) use++;
                    Convers(str[i],(use%26)+'A',aa,bb);
                    ans[l++]=aa;
                    ans[l++]=bb;
                    use++;
                    i++;
            }
            else
            {
                if(str[i]==str[i+1])
                {

                    while((use%26)+'A'==str[i]||((use%26)+'A'=='J')) use++;
                    Convers(str[i],(use%26)+'A',aa,bb);
                    ans[l++]=aa;
                    ans[l++]=bb;
                    use++;
                    i++;
                }
                else
                {

                    Convers(str[i],str[i+1],aa,bb);
                    ans[l++]=aa;
                    ans[l++]=bb;
                    i+=2;
                }
            }
        }
        ans[l]=0;
        printf("Case %d: ",++kase);
        puts(ans);
    }
    return 0;
}


 

内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值