来源  NOIP2012复赛 提高组 第一题

描述

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。

明文

H

e

l

l

o

w

o

r

l

d

密钥

a

b

c

a

b

c

a

b

c

a

密文

H

f

n

l

p

y

o

s

n

d

输入
输入共2行。
第一行为一个字符串,表示密钥k,长度不超过100,其中仅包含大小写字母。第二行为一个字符串,表示经加密后的密文,长度不超过1000,其中仅包含大小写字母。

对于100%的数据,输入的密钥的长度不超过100,输入的密文的长度不超过1000,且都仅包含英文字母。

输出
输出共1行,一个字符串,表示输入密钥和密文所对应的明文。
样例输入
CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm
样例输出
Wherethereisawillthereisaway

分析:

观察运算®的规则表格发现该表格是左下和右上对称的,也就是说:可以认为加密时行标题是明文、列标题是密钥;也可以认为加密时行标题是密钥,列标题是明文。这里我们把行标题看做明文,列标题看做密钥。

然后还可以发现:加解密运算规则表格的每一列其实是把行标题加上一个对应值就可以转换出来的。例如:表格中的第0列(即密钥为A的那一列)是把行标题各字母分别加0转换而来;表格中的第1列(密钥为B的那一列)是把行标题各字母分别加1转换而来;……以此类推,我们可以发现一个规律:

明文字母 = (密文字母-A  - (密钥字母 - A) + 26 ) mod  26 + A

上面公式里面加或减A是为了求得对应的密文字母或密钥字母在26个英文字母表当中的序号(0~25),所以需要讨论密文字母和密钥字母的大小写然后再决定是减去(或加上)大写A或小写a。具体的讨论可以看代码。

 #include <stdio.h>
int main()
{
char k[],c[];
int i,j;
char temp; scanf("%s",k);
getchar();
scanf("%s",c); for(i=,j=;c[j]!='\0';j++)
{ if(c[j]>='A'&&c[j]<='Z')
{
if(k[i]>='A'&&k[i]<='Z')
temp=(c[j]-'A'-(k[i]-'A')+)%+'A';
else temp=(c[j]-'A'-(k[i]-'a')+)%+'A';
}
else
{
if(k[i]>='A'&&k[i]<='Z')
temp=(c[j]-'a'-(k[i]-'A')+)%+'a';
else temp=(c[j]-'a'-(k[i]-'a')+)%+'a';
}
printf("%c",temp);
i++;
if(k[i]=='\0') i=;
}
return ;
}

当然,简单不费脑力的做法也可以实现,即:直接手工或者写代码构造出一个二维数组存储的运算表格,然后解密时用密钥确定列,用密文确定行即可得到明文。

Vigenère密码的更多相关文章

  1. [NOIP2012] 提高组 洛谷P1079 Vigenère 密码

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  2. NOIp 2012 #1 Vigenère 密码 Label:模拟

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  3. Vigenère 密码(luogu 1079)

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  4. Vigenère 密码NOIP 2012 提高组 第一天 第一题

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  5. NOIP2012 Vigenère 密码

    1.Vigenère 密码 (vigenere.cpp/c/pas) [问题描述] 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法——Vigenère 密码.V ...

  6. [字符串][NOIP2012]Vigenère密码

    Vigenère密码 题目描述 16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法——Vigenère密码.Vigenère密码的加密解密算法简单易用,且破译难度比较高, ...

  7. 08:Vigenère密码

    08:Vigenère密码 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法— ...

  8. 80.Vigenère密码(模拟)

    Vigenère密码(文件名vigenere.cpp   vigenere.in    vigenere.out) 题目描述 Description 16 世纪法国外交家Blaise de Vigen ...

  9. 洛谷 P1079 Vigenère 密码

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

随机推荐

  1. Android计算器尝试

    学了一段时间Android了,一直都是在看,没有什么尝试,刚好最近大致学会了gridview配合simpleadpter的使用,于是想着动手练习一下,就选择了写一个最简单的计算器来实现. 只包含+-* ...

  2. 北大poj-1005

    I Think I Need a Houseboat Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 99271   Acce ...

  3. C#变量详解

    1,变量的分类: C#是一种类型安全的语言.每一个变量都要求定义为一个特定的类型,并且要求存储在变量中的值只能是这种类型的值. 值类型 在C#中你可以通过声明枚举类型或是结构类型来定义你自己的值类型. ...

  4. CreateFile函数详解

    CreateFile函数详解 CreateFile The CreateFile function creates or opens the following objects and returns ...

  5. 安装PLSQL,登录报“无法解析指定的连接标识符的错误”

    安装PLSQL,本地不需要安装oracle服务器,但要安装oracle客户端. 一.安装客户端需要配置服务命名,tnsnames.oRA文件和监听(因为我开始没有配置监听,所以一直报无法解析制定的连接 ...

  6. UE4 Android打包 问题 记录笔记

    问题一:error: expression result unused [-Werror,-Wunused-value] 虽然看了输出日志知道了这行沉余代码删掉就行,但是不是很懂这个地方报错意义. 问 ...

  7. ajax请求!

    ajax请求: var data ='{"useName":"'+name+'",}' $.ajax({ type:"post", url: ...

  8. 关于easyui遇到的问题

    easyui中的datagrid分页中有时候会碰到context.Request["rows"]的值等于nAn的问题:这是一般都是设置的pageSize的值不在pageList里引 ...

  9. bookstore网上书店测试缺陷报告2

    Bookstore网上书店系统测试缺陷报告   缺陷编号 01.01.0002 发现人 吴赵昕 记录日期 2016-06-10 所属模块 购物车 确认人 吴赵昕 确认日期 2016-06-10 当前状 ...

  10. SQL server2000更改数据库名称

    如果是SQL Server 2005可以直接右键重命名,但是SQL Server 2000中不能直接改,可以用sp_renamedb. 1.方法一(物理法): 把Old数据库改为New数据库 打开“企 ...