p1079 vigenere 密码



题目描述

16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密

码。Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为

南军所广泛使用。

在密码学中,我们称需要加密的信息为明文,用 M 表示;称加密后的信息为密文,用

C 表示;而**是一种参数,是将明文转换为密文或将密文转换为明文的算法中输入的数据,

记为 k。 在 Vigenère 密码中,** k 是一个字母串,k=k1k2…kn。当明文 M=m1m2…mn时,

得到的密文 C=c1c2…cn,其中 ci=mi®ki,运算®的规则如下表所示:

Vigenère 加密在操作时需要注意:

  1. ®运算忽略参与运算的字母的大小写,并保持字母在明文 M 中的大小写形式;

  2. 当明文 M 的长度大于** k 的长度时,将** k 重复使用。

例如,明文 M=Helloworld,** k=abc 时,密文 C=Hfnlpyosnd。

输入输出格式

输入格式:

输入共 2 行。

第一行为一个字符串,表示** k,长度不超过 100,其中仅包含大小写字母。第二行

为一个字符串,表示经加密后的密文,长度不超过 1000,其中仅包含大小写字母。

输出格式:

输出共 1 行,一个字符串,表示输入**和密文所对应的明文。

输入输出样例

输入样例#1: 复制
CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm 
输出样例#1: 复制
Wherethereisawillthereisaway 

说明

【数据说明】

对于 100%的数据,输入的**的长度不超过 100,输入的密文的长度不超过 1000,且

都仅包含英文字母。

NOIP 2012 提高组 第一天 第一题

#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std; //字母'A'的ASCII码是41H(0100 0001B),字母'a'的ASCII码是61H(0110 0001B),//字母'Z'的ASCII码是5AH(0101  1010B), 字母'z'的ASCII码是7AH(0111 1010B) //字母'A'与'a'的二进制后5位是相同的,所以无论是大写字母还是小写字母x//x &31(1 1111B)的值就是x在字母表里的顺序。//我这是方便定位//temp记录的是向后窜的位数 //通过找规律可知,ori向后窜位的大小是key字母在字母表的顺序-1 int main(){       int i,temp; string ori,key; cin>>key>>ori; for(i=0;i<ori.size();i++) {  temp=(key[i%key.size()]&31)-1;// 括号   ori[i]=(ori[i]&31)-temp>0?ori[i]-temp:ori[i]-temp+26;//+26不就像不够借位吗?26进制。输入的是密文,所以减     }                                                        //明文变密文才是加     cout<<ori<<endl;                                          //>0,A-1==0,往后挪自然要加26  return 0;                          }