有趣的密码学介绍~古典密码之凯撒密码来咯~

在这里插入图片描述

游说万乘苦不早,著鞭跨马涉远道。仰天大笑出门去,我辈岂是蓬蒿人!

前言

Happy new year , everyone! 2022年的第一天,forever 在这里祝大家虎年快乐,希望大家在新的一年里键盘敲烂,年薪百万。

forever 因为一些缘故,接触一些关于密码学的知识,当时是以凯撒密码为话题打开的。然后自己写完之后就发现挺有趣的,觉得密码学确实博大精深,因此今天就想写一篇博客来记录并且分享一下自己学到的皮毛!

这里我们就先介绍一下古典密码学,然后在其中重点介绍一下凯撒密码吧!

正文

古典密码

一、古典密码概述介绍

古典密码编码方法归根结底主要有两种,即置换和代换。

1、置换密码

把明文中的字母重新排列,字母本身不变,但位置发生了变化,这样编成的密码称为置换密码。其中最简单的例子就是:倒序明文,即将明文的内容倒过来,然后截成固定长度的字母组作为密文。

2、代换密码

代换密码则是将明文中的字符替代成其他字符,组成的新字符就是密文。

二、古典密码分类介绍

1、置换密码

1、列置换
加密:这里是将明文按照固定长 n 分组,即每一行有 n 个字母,在密钥控制下按照某一顺序交换列,最后按照列的优先顺序依次读出,即产生了密文。解密:逆过程。
2、周期置换
一般是进行同列置换,但是在加、解密时,在列交换后是按行优先的顺序向下进行的。

2、编辑本段代换密码

1、单表代换密码
(1)加法密码
加法密码是利用明文字母在字母表中后面第 K 个字母来代替。
其加密原理为:t=(m+k) mod n;
解密:m=(t-k) mod n;
当 k = 3 时,此时就是著名的凯撒密码;凯撒密码是历史上第一个密码技术。

(2)乘法密码
加密原理:t=m*k mod n;满足条件gcd(n,k)=1,表示两个数互素,即 n 和 k 的最大公因数为1时,才能正确解密。当 n=26 时则这里与26互素的数有1、3、5、7、9、11、15、17、19、21、23、25;因此这里乘法加密的密钥空间为12;当 k=1 时,加密变换为恒等变换,即无变化。

(3)密钥词组代替密码
随机选一个词语,去掉其中的重复字母,写到矩阵的第一行,从明文字母表中去掉这一行的字母,其余字母顺序写入矩阵。然后按列取出字母构成密文字母表。
2、多表代换密码
单表代替密码的安全性不高,一个原因是一个明文字母只由一个密文文字字母代替,因此可以利用频率分析来破译。所以就产生了更为安全的多表代换密码,即构造多个密文字母表,在密钥的控制之下用一系列代换表对明文的字母序列进行代换,这样就提高了代换的次数和复杂程度。
(1)Vernam密码
(2)Playfair密码
(3)Hill密码(乘积密码)

三、编辑本段代换密码中的加法密码(凯撒密码)

凯撒密码就是编辑本段代换密码中的加法密码中的典型例子,凯撒密码它属于著名的加法密码系列。
这里我们就来讲一讲加法密码,当然凯撒密码也属于加法密码系列,因此 for ever 就带大家一起看看吧!

1、加法密码介绍

加法密码
加法密码是利用明文字母在字母表中后面第 K 个字母来代替。
其加密原理为:t=(m+k) mod n;
解密:m=(t-k) mod n;
当 k = 3 时,此时就是著名的凯撒密码;凯撒密码是历史上第一个密码技术。

2、该密码程序整体分析

此程序 forever 将其安排如下:
头文件 test.h 文件,该文件作用:库函数头文件的引用、符号的声明、函数的声明
源文件 zhizhen.cpp 文件 ,该文件作用:程序的主函数(程序主体架构)
源文件 test1.cpp 文件,该文件作用:加密函数的实现
源文件 test2.cpp 文件,该文件作用:解密函数的实现

3、该密码程序分步分析

1、test.h头文件


//头文件的引用
#include <stdio.h>
#include <string.h>
//函数的声明
void jiami(char ao, int k);//加密函数
void jiemi(char au, int k);//解密函数

2、zhizhen.cpp 源文件


#include "test.h"

//打印菜单函数
void menu()
{
    
    
	printf("———   0.exit(退出程序)   ———\n");
	printf("———  1.encryption(加密) ———\n");
	printf("———  2.deciphering(解密)———\n");
}
//主函数
int main()
{
    
    
	char AI=0;
	char AU=0;
	int k = 0;
	unsigned int n = 0;
	do
	{
    
    
		menu();
		printf("请选择:");
		scanf("%d", &n);
		AI = getchar();
		switch (n)
		{
    
    
		case 1:printf("开始加密\n");
			printf("密钥:");
			scanf("%d", &k);
			AI = getchar();
			printf("加密前文件:");
			AI = getchar();
			printf("加密后文件:");
			jiami(AI, k);//调用加密函数
			printf("\n");
			break;
		case 2:printf("开始解密\n");
			printf("密钥:");
			scanf("%d", &k);
			AU = getchar();
			printf("解密前文件:");
			AU = getchar();
			printf("解密后文件:");
			jiemi(AU, k);//调用解密函数
			printf("\n");
			break;
		case 0:printf("退出程序\n");
			break;
		default:printf("请输入合法数字\n");
		}
		printf("\n");
	} while (n);
	return 0;
}

运行结果:
在这里插入图片描述

总结:程序里面用了大量 getcgar() 函数,其中多数作用是用来吸收回车的

3、test1.cpp 源文件


#include "test.h"

//凯撒密码加密程序
void jiami(char ai, int k)
{
    
    
	while (ai != '\n')
	{
    
    
		if (ai >= 'a' && ai <= 'z')
		{
    
    
			printf("%c", (ai - 'a' + k) % 26 + 'a');//加法加密的公式
		}
		else if (ai >= 'A' && ai <= 'Z')
		{
    
    
			printf("%c", (ai - 'A' + k) % 26 + 'A');
		}
		else
		{
    
    
			printf("%c", ai);
		}
		ai = getchar();
	}
}

运行结果:
在这里插入图片描述

总结:
1、 这里密钥是k 自己输入,当 k = 3 时,就是著名的凯撒密码。
2、(ai - ‘a’ + k) % 26 + ‘a’ 这一串公式,就是加法密码再加密时候的算法公式,其原理是利用 ASCⅡ 值来计算的。

4、test2.cpp 源文件


#include "test.h"

//凯撒解密程序
void jiemi(char au, int k)
{
    
    
	while (au != '\n')
	{
    
    
		if (au >= 'a' && au <= 'z')
		{
    
    
			printf("%c", (((au - 'a' - k) % 26) + 26) % 26 + 'a');
		}
		else if (au >= 'A' && au <= 'Z')
		{
    
    
			printf("%c", (((au - 'A' - k) % 26) + 26) % 26 + 'A');
		}
		else
		{
    
    
			printf("%c", au);
		}
		au = getchar();
	}
}

运行结果:
在这里插入图片描述

总结:
1、((au - ‘a’ - k) % 26) + 26) % 26 + ‘a’) 同理,这是解密的算法公式。
2、解密的时候注意密钥输入和加密输入的密钥要相同,才能正确解密。

四、程序整体代码展示

加密密码之凯撒密码代码如下:

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

void jiami(char ao, int k);
void jiemi(char au, int k);

void menu()
{
    
    
	printf("———   0.exit(退出程序)   ———\n");
	printf("———  1.encryption(加密) ———\n");
	printf("———  2.deciphering(解密)———\n");
}
//凯撒密码加密程序
void jiami(char ai, int k)
{
    
    
	while (ai != '\n')
	{
    
    
		if (ai >= 'a' && ai <= 'z')
		{
    
    
			printf("%c", (ai - 'a' + k) % 26 + 'a');
		}
		else if (ai >= 'A' && ai <= 'Z')
		{
    
    
			printf("%c", (ai - 'A' + k) % 26 + 'A');
		}
		else
		{
    
    
			printf("%c", ai);
		}
		ai = getchar();
	}
}
//凯撒解密程序
void jiemi(char au, int k)
{
    
    
	while (au != '\n')
	{
    
    
		if (au >= 'a' && au <= 'z')
		{
    
    
			printf("%c", (((au - 'a' - k) % 26) + 26) % 26 + 'a');
		}
		else if (au >= 'A' && au <= 'Z')
		{
    
    
			printf("%c", (((au - 'A' - k) % 26) + 26) % 26 + 'A');
		}
		else
		{
    
    
			printf("%c", au);
		}
		au = getchar();
	}
}
//主函数
int main()
{
    
    
	char AI=0;
	char AU=0;
	int k = 0;
	unsigned int n = 0;
	do
	{
    
    
		menu();
		printf("请选择:");
		scanf("%d", &n);
		AI = getchar();
		switch (n)
		{
    
    
		case 1:printf("开始加密\n");
			printf("密钥:");
			scanf("%d", &k);
			AI = getchar();
			printf("加密前文件:");
			AI = getchar();
			printf("加密后文件:");
			jiami(AI, k);//调用加密函数
			printf("\n");
			break;
		case 2:printf("开始解密\n");
			printf("密钥:");
			scanf("%d", &k);
			AU = getchar();
			printf("解密前文件:");
			AU = getchar();
			printf("解密后文件:");
			jiemi(AU, k);//调用解密函数
			printf("\n");
			break;
		case 0:printf("退出程序\n");
			break;
		default:printf("请输入合法数字\n");
		}
		printf("\n");
	} while (n);
	return 0;
}

运行结果:
在这里插入图片描述

结语:

光阴似箭确实不假!送2021年的那个我,迎2022年的那个我。今天 forever 给大家介绍的密码学相关基础知识并且详细叙说了加法密码之凯撒密码。希望大家感兴趣,也望其能够帮助到一些人。如有不足或错误之处,欢迎大佬批评并指正哈!
谢谢观看!
再见啦!
以上代码均可运行,所用编译环境为 vs2019 ,运行时注意加上编译头文件#define _CRT_SECURE_NO_WARNINGS 1

Guess you like

Origin blog.csdn.net/m0_56817529/article/details/122225503