文章目录

  • 一、简介
  • 二、原理
  • 2.1 公式加密
  • 2.2 查表加密
  • 三、例题
  • 四、代码


一、简介

维吉尼亚密码(又译 维热纳尔密码 )是使用一系列凯撒密码组成密码字母表的加密算法,属于 多表密码 的一种简单形式。

维吉尼亚密码曾多次被发明。该方法最早记录在吉奥万·巴蒂斯塔·贝拉索( Giovan Battista Bellaso)于1553年所著的书《吉奥万·巴蒂斯塔·贝拉索先生的密码》(意大利语:La cifra del. Sig. Giovan Battista Bellaso)中。然而,后来在19世纪时被误传为是法国外交官布莱斯·德·维吉尼亚(Blaise De Vigenère)所创造,因此现在被称为“维吉尼亚密码”。

维吉尼亚密码以其简单易用而著称,同时初学者通常难以破解,因而又被称为“不可破译的密码”(法语:le chiffre indéchiffrable)。这也让很多人使用维吉尼亚密码来加密的目的就是为了将其破解。

二、原理

Vigengere密码使用一个词组作为密钥,第一个密钥字母加密明文的第一个字母,第二个密钥字母加密明文的第二个字母,等所有密钥字母使用完后,密钥又再循环使用。

  • 第一步可以先将密钥的长度拓展到(或者缩减到)和明文 长度一样
  • 第二步开始加密,加密的方式一般分为两种
  • ①公式加密
  • ②查表加密

2.1 公式加密

对于第一个公式加密,我们可以如下操作:
加密:维吉尼亚python爆破 维吉尼亚密码破译原理_密码学
解密:维吉尼亚python爆破 维吉尼亚密码破译原理_c++_02
其中的 维吉尼亚python爆破 维吉尼亚密码破译原理_维吉尼亚python爆破_03 表示的是密文的第 维吉尼亚python爆破 维吉尼亚密码破译原理_c++_04 个字母, 维吉尼亚python爆破 维吉尼亚密码破译原理_开发语言_05 表示的是明文的第 维吉尼亚python爆破 维吉尼亚密码破译原理_c++_04 个字母, 维吉尼亚python爆破 维吉尼亚密码破译原理_开发语言_07 表示的是密钥的第 维吉尼亚python爆破 维吉尼亚密码破译原理_c++_04

例如:

P = vigenere
K = key

(a的位置对应的是0,其余的以此类推)
得到:

v

i

g

e

n

e

r

e

k

e

y

k

e

y

k

e

维吉尼亚python爆破 维吉尼亚密码破译原理_开发语言_05

f

m

e

o

r

c

a

i

2.2 查表加密

对于每一种加密我们在一个字母表中找到我们 维吉尼亚python爆破 维吉尼亚密码破译原理_开发语言_05维吉尼亚python爆破 维吉尼亚密码破译原理_开发语言_07 对应的 维吉尼亚python爆破 维吉尼亚密码破译原理_维吉尼亚python爆破_03

例如:

给定字母表:

维吉尼亚python爆破 维吉尼亚密码破译原理_算法_15

给出查询的明文 SWPUACM 然后给出密钥:MANGATA 那么我们就能构造出来

S

W

P

U

A

C

M

M

A

N

G

A

T

A

E

W

C

A

A

V

M

三、例题

题目链接: http://acm.mangata.ltd/p/P2030

维吉尼亚python爆破 维吉尼亚密码破译原理_c++_19

四、代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 26
#define endl "\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f

void Vigenere(string P,string K){
	string C = "";
	int len1 = P.size(),len2 = K.size();
	for(int i = 0; i < len1; ++i) {
		int pos = ((P[i]-'A') + (K[i % len2] - 'A')) % mod;
		C += char('A' + pos);
	}
	cout<<"The Vigenere ciphertext = "<<C<<endl;
}

int main()
{
	string P,K;
	cout<<"Please input the plaintext"<<endl;//Encryption key
	cin>>P;
	cout<<"Please input the Encryption key"<<endl;
	cin>>K;
	transform(P.begin(),P.end(),P.begin(), ::toupper);
	transform(K.begin(),K.end(),K.begin(), ::toupper);
	Vigenere(P,K);
	return 0;
}