前言

本内容为博主学习维吉尼亚密码的笔记,如有错误,烦请指正。


一、维吉尼亚密码简介

维吉尼亚密码是一种使用多表代换的代换密码,是在凯撒密码的基础上扩展出来的多表密码。
维吉尼亚密码引入了“密钥”的概念,根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。
例子如下(密钥为deceptive):
例子

二、维吉尼亚算法

1.加密算法

维吉尼亚密码是由d个字母序列给定的密钥ki(i∈[1,d]),ki确定第i+td(t为整数)个字母的移位次数。
现代维吉尼亚密码代换表如下,第一行为密钥,第一列为明文,某明文对应密钥加密产生的密文即为该行该列处的字母。
密码表
引入头文件

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

以下加密示例区分大小写字母,统一加密为大写字母,密钥默认小写字母,加密核心算法为移位的操作,计算相对位移从’A’开始往右移,同时要注意密钥的循环,如有其他需要如密钥为大小写混合或者加密为小写字母可进行修改,加密函数代码如下:

//加密函数:统一加密为大写字母
void encrypt(char *text, char *result, char *k)
{
	int i,j=0,z=0;
	for(i=0;i<strlen(text);i++)//在明文长度内循环
	{
		if(text[i]>='a' && text[i] <= 'z')  //小写字母
			result[z]=(text[i]-'a'+k[j]-'a')%26 +'A';
		else								//大写字母
			result[z]=(text[i]-'A'+k[j]-'a')%26 +'A';
		j++;
		if(j>=strlen(k)) j=0;//以密钥长度为一个周期循环
		z++;
	}
}

2.解密算法

解密算法为逆着加密的方法移位回去即可,此处统一解密为小写字母。

//解密函数:统一解密为小写字母
void decrypt(char *text, char *result, char *k)
{
	int i,j=0,z=0;
	for(i=0;i<strlen(text);i++)
	{
		if(text[i]>='a' && text[i] <= 'z')//小写字母
			result[z]=(text[i]-k[j]+26)%26 +'a';
		else                              //大写字母
			result[z]=(text[i]-k[j]+58)%26 +'a';
		j++;
		if(j>=strlen(k)) j=0;//以密钥长度为一个周期循环
		z++;
	}
}

3.主函数

测试主函数代码如下:

void main()
{
	int type;
	printf("欢迎来到维吉尼亚密码系统!");
	while(1)
	{
		char text[99]="";
		char result[99]="";
		char k[99]="";
		printf("\n0:退出 1:加密 2:解密\n");
		printf("请输入你的选择:");
		scanf("%d",&type);
		if(type == 0)
		{
			printf("系统退出。\n");
			break;
		}
		printf("请输入一段英文字母:");//默认输入为一段连续英文字母串
		scanf("%s",text);
		printf("请输入密钥:");//密钥默认小写
		scanf("%s",k);
		if(type ==1)
		{	
			encrypt(text,result,k);
			printf("密文为:%s\n",result);//输出密文
		}
		else if(type == 2)
		{
			decrypt(text,result,k);
			printf("明文为:%s\n",result);//输出明文
		}
		else
			printf("输入有误!请重新输入!\n");
	}
}

测试用例如下:
测试


总结

维吉尼亚密码的优势在于这种密码被假定为它将不同位置的字母进行不同的加密,很多年来一直认为维吉尼亚密码是无法破解的,但19世纪50年代一位英国富人查尔斯·巴贝奇通过寻找重复的字母段破解了这个密码系统。 在任何比密钥要长得多的加密信息中,都会不可避免地出现类似这样的重复。而一个解密者应该如何才能揭示加密文件的真正面目呢?比如,如果加密文字"UPK"出现了两次,第一个"U"到下一个"U"会数21个字母,那么他就可以推断出密钥的长度是21的整除数。或者换种说法,他可以推断出21是密钥的倍数。 如果获得了足够多类似的线索,解密者就可以知道密钥的确切长度。一旦他知道了密钥长度,他就可以对加密信息进行日常频率分析。
经过学习,编程搞定了维吉尼亚密码算法,也算是比较简单的一个加密密码算法,但在过程中还是由于加解密的逻辑问题导致bug不断,不过只要多尝试及计算还是可以解决的。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐