【网络安全】【密码学】【北京航空航天大学】实验五、古典密码(中)【C语言实现】

实验五、古典密码(中)

实验目的原理简介参见博客:古典密码(上)

一、实验内容

1、弗纳姆密码(Vernam Cipher)

(1)、算法原理

加密原理:
加密过程可以用方程 ci = pi (+) ki 表示,其中 pi 是明文第 i 个二进制位,ki 是密钥第 i 个二进制位,ci 是密文第 i 个二进制位,(+)异或运算符。密文是通过对明文和密钥的逐位异或而成的。

解密原理:
根据异或运算的性质,解密过程可以用方程 pi = ci (+) ki 表示,其中 pi 是明文第 i 个二进制位,ki 是密钥第 i 个二进制位,ci 是密文第i个二进制位,(+) 是异或运算符。

(2)、算法的代码实现(C语言)

使用文件进行读/写,而非从终端中直接输入明/密文。(此程序存在bug,正在修复中)

#include <stdio.h>
#include <string.h>

char plaintext[10010] = { 0 };  // 明文
char ciphertext[10010] = { 0 };  // 密文

char key[10010] = { 0 };  // 密钥

void encrypt(char plaintext[], char key[]);  // 加密函数
void decrypt(char ciphertext[], char key[]);  // 解密函数

int main()
{
	char a;
	int i = 0;
	
	printf("该程序实现弗纳姆密码。请输入密钥:\n");
	gets(key);
	
	
	int input;
	printf("请输入选项:1为加密;2为解密\n");
	scanf("%d", &input);
	
	if(input == 1)
	{
		// 加密
		printf("******加密中******\n\n");
		encrypt(plaintext, key);
		printf("******加密完成******\n");
	}
	
	else if(input == 2)
	{
		// 解密
		printf("******解密中******\n\n");
		decrypt(ciphertext, key);
		printf("******解密完成******\n");
	}
	
	else
		printf("错误的选项(只能为1或2)。程序退出。");
	
	return 0;
}

void encrypt(char plaintext[], char key[])
{
	FILE *in, *out;
	in = fopen("input1.txt", "r");
	out = fopen("output1.txt", "w");
	char a;
	int i;
	int j;
	while((a = fgetc(in)) != EOF)
	{
		plaintext[i ++] = a;
	}
	for(j = 0;j < i;j ++)
	{
		ciphertext[j] = plaintext[j] ^ key[j % strlen(key)];
	}
	fputs(ciphertext, out);
	fclose(in);
	fclose(out);
	return;
}

void decrypt(char ciphertext[], char key[])
{
	FILE *in, *out;
	in = fopen("input2.txt", "r");
	out = fopen("output2.txt", "w");
	char a;
	int i;
	int j;
	while((a = fgetc(in)) != EOF)
	{
		ciphertext[i ++] = a;
	}
	for(j = 0;j < i;j ++)
	{
		plaintext[j] = ciphertext[j] ^ key[j % strlen(key)];
	}
	fputs(plaintext, out);
	fclose(in);
	fclose(out);
	return;	
}

(3)、算法测试

加密过程演示:

明文:(位于input1.txt中):

Here lies a toppled god - His fall was not a small one. We did but build his pedestal, A narrow and a tall one. - Tleilaxu Epigram

(语出弗兰克·赫伯特 Frank Herbert 的《沙丘:救世主 Dune: Messiah》,简单翻译过来是:这里躺着一个被推翻的神明——他轰然倒下。我们未曾有他助——只是将他供奉起来,让他如履薄冰。)

密钥:crucible (考验)

(插一句,借鉴(特别是二战)历史和经典谍战电影,双方在加密通信时使用某本书中约定好的某个单词,这里crucible是《沙丘:救世主》(原)书第125页的第1个单词。)

密文:(位于output1.txt中,为非打印(可见)字符。)

运行截图:

在这里插入图片描述

解密过程演示(恢复明文):

密文:(位于input2.txt中,内容为加密后的输出)

密钥:crucible(和加密过程所用密钥相同)

明文:(位于output2.txt中):

Here lies a toppled god - His fall was not a small one. We did but build his pedestal, A narrow and a tall one. - Tleilaxu Epigram

运行截图:

在这里插入图片描述

2、栅栏密码(Fence Cipher)

(1)、算法原理

加密原理:
栅栏密码按照列的顺序将明文(去掉空格)写入m行n列的数组,按照行的顺序将字符重新组合得到密文,这种方式称为m栏栅栏密码。

解密原理:
首先将密文分成n组,n为数组的行数,然后按照列的顺序将密文进行重新组合,最后将组合后的字符拼接起来,得到密文。

直观举例

明文
One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them…

(语出J.R.R. 托尔金魔戒 The Lord of the Rings》卷首,拙劣翻译为:一戒统御众人,一戒寻其踪迹,一戒召其而来,将其束于黑暗。)

首先去掉标点,变成:
OneRingtorulethemallOneRingtofindthemOneRingtobringthemallandinthedarknessbindthem,一个长“单词”,共82个字母:

在这里插入图片描述

写成一个10行9列(多余2个字母)的矩阵,竖读为明文,横读为密文:

在这里插入图片描述

(2)、算法的代码实现(C语言)

#include <stdio.h>
#include <string.h>

char plaintext[10010] = { 0 };
char ciphertext[10010] = { 0 };
char table[10010][10010] = { '*' };

void encrypt(char plaintext[], int n);
void decrypt(char ciphertext[], int n);

int n;  //行数 
int i, j, k;
int a, b; //len = a * n + b
int len;  //明文、密文的长度 

int main()
{	
	int input;
	printf("该程序实现栅栏密码。请输入选项:1为加密;2为解密\n");
	scanf("%d", &input);
	
	if(input == 1)
	{
		// 加密
		printf("请输入要加密的明文:\n");
		scanf("%s", plaintext);
		printf("请输入行数:\n");
		scanf("%d", &n);
		printf("加密结果:\n");
		encrypt(plaintext, n);
	}
	
	else if(input == 2)
	{
		// 解密
		printf("请输入要解密的密文:\n");
		scanf("%s", ciphertext);
		printf("请输入行数:\n");
		scanf("%d", &n);
		printf("解密结果:\n");
		decrypt(ciphertext, n);
	}
	
	else
		printf("错误的选项(只能为1或2)。程序退出。");
	
	return 0;
}

void encrypt(char plaintext[], int n)
{
	for(j = 0;j < n;j ++)
	{
		for(i = 0;i < strlen(plaintext);i ++)
		{
		    if(i % n == j)
			{
		    	putchar(plaintext[i]);
			}
		}
	}
	return;
}

void decrypt(char ciphertext[], int n)
{
	k = 0;
	len = strlen(ciphertext);
	a = len / n;
	b = len - a * n;
	//printf("%d %d", a, b);
	for(i = 0;i < b;i ++)
	{
		for(j = 0;j < a + 1;j ++)
		{
			table[i][j] = ciphertext[k ++];
		}
	}
	for(i = b;i < n;i ++)
	{
		for(j = 0;j < a;j ++)
		{
			table[i][j] = ciphertext[k ++];
		}
	}
	for(j = 0;j < a;j ++)
	{
		for(i = 0;i < n;i ++)
		{
			putchar(table[i][j]);
		}
	}
	for(i = 0;i < b;i ++)
	{
		putchar(table[i][a]);
	}
	return;
}

(3)、算法测试

使用上述例子中的明文进行测试,n(行数)为10.

加密过程:

在这里插入图片描述

解密过程:

在这里插入图片描述

成功恢复出明文。

二、参考文献

1、《密码编码学与网络安全——原理与实践(第七版)》(Cryptography and Network Security, Principles and Practice, Seventh Edition),【美】威廉 斯托林斯 William Stallings 著,王后珍等 译,北京,电子工业出版社,2017年12月。

2、《密码学实验教程》,郭华 刘建伟等 主编,北京,电子工业出版社,2021年1月。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/337654.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多线程-Thread类及常见方法

目录 1.什么是Thread类 1.1Thread 的常⻅构造⽅法 1.2 Thread 的⼏个常⻅属性 2.启动⼀个线程 - start() 经典面试题&#xff1a;start 和run 区别 3.中断⼀个线程 方法一&#xff1a; 方法二: 4.等待⼀个线程 - join() 5. 获取当前线程引用 方法一&#xff1a; 方法二…

【Linux】—— 命名管道详解

命名管道是一种在操作系统中用于进程间通信的机制&#xff0c;它允许不同的进程之间通过管道进行数据交换。与匿名管道相比&#xff0c;命名管道具有更多的灵活性和功能。在本博客中&#xff0c;我们将深入探讨命名管道的概念、用途以及如何在编程中使用它们。 目录 &#xff…

多线程(看这一篇就够了,超详细,满满的干货)

多线程 一.认识线程&#xff08;Thread&#xff09;1. 1) 线程是什么1. 2) 为啥要有线程1.3) 进程和线程的区别标题1.4) Java的线程和操作系统线程的关系 二.创建线程方法1:继承Thread类方法2:实现Runnable接口方法3:匿名内部类创建Thread子类对象标题方法4:匿名内部类创建Runn…

139:leafle加载here地图(v3软件多种形式)

第139个 点击查看专栏目录 本示例介绍如何在vue+leaflet中添加HERE地图(v3版本的软件),并且含多种的表现形式。包括地图类型,文字标记的设置、语言的选择、PPI的设定。 v3版本和v2版本有很大的区别,关键是引用方法上,请参考文章尾部的API链接。 直接复制下面的 vue+leaf…

SpringCloud之Nacos的学习、快速上手

1、什么是Nacos Nacos是阿里的一个开源产品&#xff0c;是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案&#xff0c;用来实现配置中心和服务注册中心。 Nacos 快速开始 2、安装运行nacos nacos下载地址 下载地址: https://github.com/alibaba/nacos/rel…

冒泡排序-BubbleSort

1、基本思路 从数组的左边开始&#xff0c;比较两个元素的大小&#xff0c;当左边大于右边时&#xff0c;更换左右元素位置&#xff0c;否则不改变&#xff1b;接着向右移动一步&#xff0c;比较第二个元素和第三个元素的大小&#xff0c;重复上述操作&#xff0c;直到最后一个…

VMware workstation安装FreeBSD14.0虚拟机并配置网络

VMware workstation安装FreeBSD14.0虚拟机并配置网络 FreeBSD是类UNIX操作系统&#xff0c;FreeBSD带有多个软件包&#xff0c;并覆盖了广阔的应用领域&#xff0c;且都是免费和易于安装的。该文档适用于在VMware workstation平台安装FreeBSD14.0虚拟机。 1.安装准备 1.1安装…

Spring+SprinMVC+MyBatis配置方式简易模板

SpringSprinMVCMyBatis配置方式简易模板代码Demo GitHub访问 ssm-tpl-cfg 一、SQL数据准备 创建数据库test&#xff0c;执行下方SQL创建表ssm-tpl-cfg /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Versio…

QCustomPlot 曲线数据结构与存取

对了&#xff0c;我开通了微信公众号&#xff0c;计划是两边会同步更新&#xff0c;并逐步的会将博客上的文章同步至公众号中。感兴趣的朋友可以搜索“里先森sements”来关注&#xff0c;欢迎来玩~&#xff01; 通常&#xff0c;我们对QCustomPlot中的曲线数据无外乎增、删、改…

xshell配置隧道转移规则

钢铁知识库&#xff0c;一个学习python爬虫、数据分析的知识库。人生苦短&#xff0c;快用python。 xshell是什么 通俗点说就是一款强大ssh远程软件&#xff0c;可以方便运维人员对服务器进行管理操作&#xff0c;功能很多朋友们自行探索&#xff0c;今天只聊其中一个功能点那…

【RHCSA服务搭建实验】之apache

虚拟web主机类型 一、基于端口 1.vim /etc/httpd/conf.d/vhost2.conf ---- — 改变http服务默认访问路径 <directory /testweb1>allowoverride none 表示不允许覆盖其他配置require all granted 表示允许所有请求 </directory> <virtualhost 0.0.0.0:…

分布式系统中为什么需要使用消息队列

本文转载自 linkedkeeper.com 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能&#xff0c;成为异步RPC的主要手段之一。 当今市面上有很多主流的消息中间件&#xff0c;如老牌的ActiveMQ、RabbitMQ&#…

【Docker】使用Docker安装Nginx及部署前后端分离项目应用

一、Nginx介绍 Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。它是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的&#xff0c;公开版本1.19.6发布于2020年12月15日。其将源代码以类BSD许可证的形式发布&#xff0c;因它…

RLC如何通过改变频率实现输出稳压

当开关频率工作在容性区域时&#xff0c;容抗抵消完感抗还有剩余&#xff0c;所以容抗感抗可以近似为一个容抗Cr,但加上频率的改变&#xff0c;容抗又可以近似为一个可调电阻 那又改如何控制频率&#xff0c;保持输出稳压&#xff1f; 当输入与输出电压不变时&#xff0c;Rac变…

尝试解决githubclone失败问题

BV1qV4y1m7PB 根据这个视频 似乎是我的linux的github似乎下好了 我没有配置好 比如我的ssh-key 现在根据视频试试 首先需要跳转到ssh的文件夹&#xff1a; cd ~/.ssh 然后生成一个ssh-key&#xff1a; ssh-keygen -t rsa -C "<github资料里的邮箱>" 然后…

Python(18)--文件输入/输出 Ⅱ

​ 大家好&#xff01;我是码银&#x1f970; 欢迎关注&#x1f970;&#xff1a; CSDN&#xff1a;码银 公众号&#xff1a;码银学编程 前言 前一篇文章&#xff08;python(17)–文件的输入/输出-CSDN博客&#xff09;介绍了如何操作文本文件和二进制文件&#xff0c;以及对应…

跨站点请求伪造攻击 - Cross Site Request Forgery (CSRF)

什么是CSRF 最好理解CSRF攻击的方式是看一个具体的例子。 假设你的银行网站提供一个表单,允许当前登录用户将钱转账到另一个银行账户。例如,转账表单可能如下所示: <form method="post"action="/transfer"> <

SpringBoot 更新业务场景下,如何区分null是清空属性值 还是null为vo属性默认值?

先看歧义现象 值为null 未传递此属性 所以此时如何区分null 时传递进来的的null&#xff0c;还是属性的默认值null? 引入方案 引入过滤器&#xff0c;中间截获requestBodyData并保存到HttpServletRequest&#xff0c;业务层从HttpServletRequest 获取到requestBodyData辅…

PCIe 5.0硬件

一、PCIe 5.0概述 (1)什么是PCIe 5.0 第五代快速周边组件互连称为PCI Express 5.0(Peripheral Component Interconnect Express 5.0),也称为第五代PCIe、PCIe 5、PCI v5或简称为PCIe 5.0。PCIe技术于2003年首次推出,现已成为使用点对点访问总线将高速组件连接到主板的标准接…

基于springboot的一个IT人才招聘网站系统源码+数据库+部署文档,公司可以发布岗位需求,求职者查找岗位并递交简历等

介绍 实现一个IT人才招聘系统&#xff0c;公司可以发布岗位需求&#xff0c;求职者查找岗位并递交简历等 启动 1. 主要技术版本 技术名称版本SpringBoot2.5.0MySQL8.0Redis6.2.0 2. 本地启动部署 2.1 数据库数据源部署 src/main/resources/application.yaml 配置文件&am…