信息安全导论 实验一 古典密码学

这篇博客介绍了如何使用C++和Python实现古典密码学中的移位密码和维吉尼亚密码算法。移位密码通过字母移位实现加密解密,而维吉尼亚密码是一种多表代换密码,利用密钥与明文的对应关系进行加密。文章提供了详细的算法原理、参数说明及示例代码,展示了如何对明文进行加密和解密操作。
摘要由CSDN通过智能技术生成

一、实验目的与原理

1.实现古典密码学中的移位密码算法和维吉尼亚算法。

2.了解两种算法的原理,并且编写出来。

3.使用语言为C++或者Python等。

二、实验内容与记录

位移密码算法:

移位密码算法

在加密的时候需要注意大小写的转换,这个可以调用c++的<sstream>库中的函数进行解决。

1) 算法原理

a) 移位密码就是对26个字母进行移位操作,可以移动任意位数,这样就实现了对明文的加密,移位操作简单易行,因此,加密解密比较简单。

b) 移位密码的基本思想:移位密码算法 c=m+k(mod 26),k可以使0<k<26的任意整数。加密算法:x=x+k(mod26),解密算法x=x-k(mod 26)。当K=3,时,为凯撒密码。

2) 算法参数

移位密码算法主要有c、m、k 三个参数。c 为密文,m 是明文,k 为密钥。

输入

第一行输入表明是加密还是解密,0是加密,1是解密;

第二行是加密或解密密钥,是0<k<26之间的一个整数;

第三行是明文或密文。

输出

输出是明文或密文。

输入样例1 

0
6
wearesztuers
1
6
CKGXKYFZAKXY

输出样例1

CKGXKYFZAKXY
wearesztuers

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<sstream>
using namespace std;
string fx1(string text, int x, int y) {
	char cha = ' ';
    string truein;
	if (y == 0) {
		x = -1 * x;
	}
	char location = 'a';
	int length = 26;
	for (int i = 0; i < text.length(); i++) {
		//最终返回的字符串

		bool pan = false;
		char str = text[i];
		//判断是否大小写
		if (isupper(str)) {
			pan = true;
			//大写字母转换为小写
			str = tolower(str);
		}
		//位置改变
		int prelocation = str - location;
		//算法执行
		int offset = (prelocation + x) % length;
		if (offset < 0) {
			offset += length;
		}
		cha = (char)(location + offset);
		//小写转换大写
		if (!pan) {
			cha = toupper(cha);
		}
		truein += cha;
	}
	return truein;
}
int main()
{
	for(int j=0;j<2;j++) {
		//way是加密或者解密,key是密钥,text1是密文 
		int way, key, temp;
		string text1;
		cin >> way >> key;
		cin >> text1;
		int cost;
		if (way == 0) {
			cost = 1;
		}
		else {
			cost = 0;
		}
		string text2=fx1(text1, key, cost);
		cout<<text2<<endl;
		text2=" ";
	}
}

维吉尼亚算法:

维吉尼亚算法与移位算法相近,维吉尼亚算法可以想象成:应用到一个二维表格,横坐标是密钥,纵坐标是明文,两者相交的点是密文。

1) 算法原理

a) Vigenere密码是由法国密码学家Blaise de Vigenere于1858年提出的一种代换密码,它是多表代换密码的典型代表。

b) 定义:设m为某一固定的正整数,P、C和K分别为明文空间、密文空间和密钥空间,并且P=K=C=(Z26)m,对一个密钥k=(k1,k2,…,km),定义维吉尼亚密码的加解密算法如下:

Vigenere密码加密算法: ek(x1,x2,…,xm)=(x1+k1,x2+k2,…,xm+km)

Vigenere密码解密算法: dk(y1,y2,…,ym)=(y1-k1,y2-k2,…,ym-km)。

其中k=(k1,k2,…,km)是一个长为m的密钥字,密钥空间的大小为26m,所以对一个相对小的m,穷举密钥也需要很长的时间。如m=7,则密钥空间大小超过8×109,所以手工搜索非常困难。当明文的长度超过m时,可将明文串按长度m分局,然后对每一组使用密钥k加密。

2) 算法参数

Vigenere密码算法主要有c、m、k三个个参数。c为密文,m是明文,k为密钥。

输入

第一行输入明文

第二行输入密钥

输出

第一行输出密文

第二行输出密文解密后得到的明文

输入样例1

xipuyangguang
best

输出样例1

ymhnzefzhysgh
xipuyangguang

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<sstream>
#include <algorithm>
using namespace std;
//加密函数 
string fx1(string x, string y, int temp) {
	string truein;
	char cha = ' ';
	//定义起始末尾,长度等 
	char location = 'a';
	int index = 0, length = 26;
	transform(y.begin(), y.end(), y.begin(), ::tolower);
	for (int i = 0; i < x.length(); i++) {
		bool pan = false;
		char str = x[i];
		//判断大小写字母 
		if (isupper(str)) {
			pan = true;
			str = tolower(str);
		}
		//计算相对长度 
		index %= y.length();
		int nextlocation = str - location;
		int way = y[index] - location;
		if (temp == 0) {
			way = way * -1;
		}
		int offset = (nextlocation + way) % length;
		if (offset < 0) {
			offset += length;
		}
		cha = (char)(location + offset);
		if (pan) {
			cha = toupper(cha);
		}
		truein += cha;
		index++;
	}
	return truein;
}
//解密函数
string fx2(string x, string y, int temp) {
	string truein;
	char cha = ' ';
	//定义起始末尾,长度等 
	char location = 'a';
	int index = 0;
	int length = 26;
	//小写转换
	transform(y.begin(), y.end(), y.begin(), ::tolower);
	for (int i = 0; i < x.length(); i++) {
		bool pan = false;
		char str = x[i];
		//判断大小写字母 
		if (isupper(str)) {
			pan = true;
			str = tolower(str);
		}
		//计算相对长度 
		index %= y.length();
		int prelocation = str - location;
		int way = y[index] - location;
		if (temp == 0) {
			way = way * -1;
		}
		int offset = (prelocation + way) % length;
		if (offset < 0) {
			offset += length;
		}
		cha = (char)(location + offset);
		if (pan) {
			cha = toupper(cha);
		}
		truein += cha;
		index++;
	}
	return truein;
}
int main() {
	string x, y;
	cin >> x >> y;
	//加密函数 
	string str1 = fx1(x, y, 1);
	cout << str1 << endl;
	//解密函数 
	string str2 = fx2(str1, y, 0);
	cout << str2;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stearm210

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值