Vigenère密码

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 来源  NOIP2012复赛 提高组 第一题描述16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法——Vigenère密码。Vigenère密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为南军所广泛使用。

来源  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。具体的讨论可以看代码。

 1 #include <stdio.h>
 2 int main()
 3 {
 4     char k[102],c[1002];
 5     int i,j;
 6     char temp;
 7 
 8     scanf("%s",k);
 9     getchar();
10     scanf("%s",c);
11 
12     for(i=0,j=0;c[j]!='\0';j++)
13     {
14 
15         if(c[j]>='A'&&c[j]<='Z')
16         {
17             if(k[i]>='A'&&k[i]<='Z')
18                 temp=(c[j]-'A'-(k[i]-'A')+26)%26+'A';
19             else  temp=(c[j]-'A'-(k[i]-'a')+26)%26+'A';
20         }
21         else
22         {
23             if(k[i]>='A'&&k[i]<='Z')
24                 temp=(c[j]-'a'-(k[i]-'A')+26)%26+'a';
25             else temp=(c[j]-'a'-(k[i]-'a')+26)%26+'a';
26         }
27         printf("%c",temp);
28         i++;
29         if(k[i]=='\0') i=0;
30     }
31     return 0;
32 }

 

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

相关文章
|
5月前
|
数据安全/隐私保护
登录中用于记住用户名和密码的方法
登录中用于记住用户名和密码的方法
47 0
|
7月前
|
安全 数据安全/隐私保护
如何安全的使用密码登录账号(在不知道密码的情况下)
该内容介绍了如何使用一个工具来便捷地复制和管理账号密码。首先提到了两个下载工具的链接,分别是百度网盘和蓝奏云,并给出了相应的提取码。接着,展示了工具的界面,说明通过按住Ctrl或Alt点击密码栏可以快速复制账号和密码,无需直接看到密码。用户可以通过模拟添加账号来体验这一功能,然后演示了如何生成和复制新密码。最后,重点强调了按住Ctrl复制账号和按住Alt复制对应密码的快捷操作,使得在不知密码的情况下也能轻松获取。
|
7月前
|
存储 安全 网络安全
如何取安全的密码?
如何取安全的密码?
64 0
|
7月前
|
存储 弹性计算 运维
循环测试用户名与密码是否正确
【4月更文挑战第29天】
38 0
|
7月前
|
存储 弹性计算 运维
测试用户名与密码是否正确
【4月更文挑战第29天】
46 0
|
Linux 数据安全/隐私保护
ADFGVX密码
ADFGVX密码
135 0
|
数据安全/隐私保护 计算机视觉
QWE密码
QWE密码
367 0
|
Linux 数据安全/隐私保护 知识图谱
ADFGX密码
ADFGX密码
261 0
|
机器学习/深度学习 Linux 数据安全/隐私保护
维吉尼亚密码(Vigenere)
维吉尼亚密码(Vigenere)
208 0
|
Linux 数据安全/隐私保护
普莱费尔密码(playfair)
普莱费尔密码(playfair)
270 0