洛谷----P1079 Vigenère 密碼(知識點學習)

0k-ok發表於2020-11-09

舊人舊事更值得懷念,或悲或喜每個人身上都承載著某一段時光,但是我會永遠清澈永遠瘋狂永遠浪漫。沒有人能回到過去重新活過,但你我都可以從現在開始,決定我們未來的模樣。
                                                                                                                                                                           ----喻言

 

題目描述

16 世紀法國外交家 Blaise de Vigenère 設計了一種多表密碼加密演算法 Vigenère 密碼。Vigenère 密碼的加密解密演算法簡單易用,且破譯難度比較高,曾在美國南北戰爭中為南軍所廣泛使用。

在密碼學中,我們稱需要加密的資訊為明文,用 MM 表示;稱加密後的資訊為密文,用 CC 表示;而金鑰是一種引數,是將明文轉換為密文或將密文轉換為明文的演算法中輸入的資料,記為 kk。 在 Vigenère 密碼中,金鑰 kk 是一個字母串,k=k_1,k_2,…,k_nk=k1​,k2​,…,kn​。當明文 M=m_1,m_2,…,m_nM=m1​,m2​,…,mn​ 時,得到的密文 C=c_1,c_2,…,c_nC=c1​,c2​,…,cn​,其中 c_ici​=m_imi​®k_iki​,運算®的規則如下表所示:

Vigenère 加密在操作時需要注意:

  1. ®運算忽略參與運算的字母的大小寫,並保持字母在明文 MM 中的大小寫形式;

  2. 當明文 MM 的長度大於金鑰 kk 的長度時,將金鑰 kk 重複使用。

例如,明文 M=\texttt{Helloworld}M=Helloworld,金鑰 k=\texttt{abc}k=abc 時,密文 C=\texttt{Hfnlpyosnd}C=Hfnlpyosnd。

輸入格式

共 2 行。

第一行為一個字串,表示金鑰 kk,長度不超過 100100,其中僅包含大小寫字母。

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

輸出格式

一個字串,表示輸入金鑰和密文所對應的明文。

輸入輸出樣例

輸入 #1複製

CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm

輸出 #1複製

Wherethereisawillthereisaway

說明/提示

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

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cctype>
#include <bitset>
#include <utility>
#include <complex>
#include <iomanip>
#include <numeric>
#include<unordered_set>
#include <climits>//INT_100010n
#include <regex>
//#include<bits/stdc++.h>
#define PP pair<ll,int>
#define inf 0x3f3f3f3f
#define INF 0x7fffffff;
#define llinf 0x3f3f3f3f3f3f3f3fll
#define dinf 1000000000000.0
#define PI 3.1415926
#define LL unsigned int
#define mod 1000000007
#define wc 1e-18
typedef long long ll;
using namespace std;
string k,c;
int main()
{
    cin>>k>>c;
    for (int i=0; i<c.length(); i++)
    {
        //x&31(11111B)的值就是x在字母表裡的順序。
        int t=(k[i%k.length()]&31)-1;
        c[i]=(c[i]&31)-t>0?c[i]-t:c[i]-t+26;
    }
    cout<<c<<endl;
    return 0;
}

 

相關文章