第六章 函數-1402:Vigenère密碼

1402:Vigenère密碼

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 6704 通過數: 3761
【題目描述】
6世紀法國外交家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。

在這裏插入圖片描述

【輸入】
第一行爲一個字符串,表示密鑰k,長度不超過100,其中僅包含大小寫字母。

第二行爲一個字符串,表示經加密後的密文,長度不超過1000,其中僅包含大小寫字母。

對於100%的數據,輸入的密鑰的長度不超過100,輸入的密文的長度不超過1000,且都僅包含英文字母。

【輸出】
輸出共1行,一個字符串,表示輸入密鑰和密文所對應的明文。

【輸入樣例】
CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm
【輸出樣例】
Wherethereisawillthereisaway


思路:將密鑰轉換爲大寫字母,從頭開始解密,大寫的情況,按規則解密,若明文小於A,從字母表倒序轉換。小寫的情況,按規則解密,若明文小於a,從字母表倒序轉換,若明文長度大於密鑰長度,重複使用密鑰。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

void turn(char &x)
{
    if((x >= 'a') && (x <= 'z'))
        x -= 32;
}
int main()
{
    char key[1000],s[1000];
    int lena,lenb;
    int i,j;
 
    gets(key);//輸入密鑰
    gets(s);//輸入密文
    lena=strlen(key);//求密鑰長度
    lenb=strlen(s);//求密文長度
 
    for(i = 0; i < lena; i++) //將密鑰轉換爲大寫字母
        turn(key[i]);
 
    for(i=0,j = 0; i < lenb; i++) //從頭開始解密
    {
        if(s[i] <= 'Z')//大寫的情況
        {
            s[i] = s[i] - (key[j]-'A');//按規則解密
            j++;
            if(s[i] < 'A')//若明文小於A
                s[i] = 'Z'-('A'-s[i])+1;//從字母表倒序轉換
        }
        else//小寫的情況
        {
            s[i] = s[i] - (key[j]-'A');//按規則解密
            j++;
            if(s[i] < 'a')//若明文小於a
                s[i] = 'z' - ('a'-s[i]) + 1;//從字母表倒序轉換
        }
        if(j > lena - 1)//若明文長度大於密鑰長度,重複使用密鑰
            j = 0;
    }
    cout << s << endl;
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章