简单加密-维吉尼亚

  

  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
-------------------------------------------------------------------
题解如下:
  看到这个密码表有没有想到二维数组和ASCI
1 #include<stdio.h>
 2 #include<string.h>
 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就不再赋值
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 < lenk; i++)
36     {
37         j++;
38         if (k[j] == '') 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 < lenk; 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 }
 
原文地址:https://www.cnblogs.com/mwq1024/p/10098182.html