作者:心若在梦就在_2012 | 来源:互联网 | 2023-10-11 19:25
16世纪法国外交家BlaisedeVigenère设计了一种多表密码加密算法——Vigenère密码。Vigenère密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北
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行。
第一行为一个字符串,表示明文M,长度不超过1000,其中仅包含大小写英文字母。
第二行为一个字符串,表示密钥K,长度不超过100,其中仅包含大小写英文字母。
输出
输出共1行,一个字符串,表示加密后的密文。
样例输入
请输入明文:Helloworld
请输入密匙:abc
样例输出
密文:Hfnlpyosnd
-------------------------------------------------------------------
题解如下:
看到这个密码表有没有想到二维数组和ASCII码?
1 #include
2 #include
3
4 void Vigenere(char m[], char k[]) {
5 //创建密码表
6 char Encryption_table[26][26];
7 int i, j, flag = 97, top;
8 //密码表分两部分 第一部分是以“Z”为对角线的上部分,第二部分则为下部分
9 //这个for循环创建密码表的第一部分
10 for (i = 0; i <26; i++)
11 {
12
13 top = flag;//因为大部分明文是小写,所以top从’a‘开始创建小写密码表
14 for (j = 0; j <26; j++) {
15 Encryption_table[i][j] = top;
16 top++;
17 if (top > 122) break;//如果top的ASCII码值超过了122(即赋值完'z')就不再往下赋值
18 }
19 flag++;//更新起始值 (每一行的第一个元素都比上一行大 1 )
20 }
21 //这个for循环创建密码表的第二部分
22 //从第二行开始密码表不全 所以i=1
23 for (i = 1; i <26; i++) {
24 flag = 97;
25 for (j = 26 - i; j <26; j++)
26 {//j=26-i 寻找每行’a'的起始位置
27 Encryption_table[i][j] = flag;
28 flag++;
29 }
30 }
31
32
33 char C[1000];
34 int lenk = strlen(m);
35 for (j = -1, i = 0; i 36 {
37 j++;
38 if (k[j] == '\0') j = 0; //判断密匙是否用完,如果用完就从第一个元素重新使用
39 //密匙与明文大小写的四种状态
40 if (m[i] >= 97 && k[j] >= 97)
41 {
42 C[i] = Encryption_table[m[i] - 97][k[j] - 97];
43 continue;
44 }
45 if (m[i] <97 && k[j] <97) {
46 m[i] = m[i] + 32; k[j] = k[j] + 32; C[i] = Encryption_table[m[i] - 97][k[j] - 97] - 32;
47 continue;
48 }
49 if (m[i] <97 && k[j] >= 97) {
50 m[i] = m[i] + 32; C[i] = Encryption_table[m[i] - 97][k[j] - 97] - 32;
51 continue;
52 }
53 if (m[i] >= 97 && k[j] <97) {
54 k[j] = k[j] + 32; C[i] = Encryption_table[m[i] - 97][k[j] - 97];
55 continue;
56 }
57
58 }
59 printf("密文:");
60 for (i = 0; i 61 {
62 printf("%c", C[i]);
63 }
64 }
65 int main()
66 {
67 char m[1000], k[100];
68 printf("请输入明文:");
69 gets_s(m);
70 printf("请输入密匙:");
71 gets_s(k);
72 Vigenere(m, k);
73 }