• 简单加密-维吉尼亚


      

      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 }
     
  • 相关阅读:
    处理火星文重温vchar,char,nvchar,nchar
    删除文件
    js常用正则表达式
    安装iis 配置iis
    无题
    js函数大全
    常用正则表达式
    QQ在线客服
    获取系统文字字体
    无限级删除的存储过程
  • 原文地址:https://www.cnblogs.com/mwq1024/p/10098182.html
Copyright © 2020-2023  润新知