多字符代换密码

本文介绍了多字符代换密码的概念,它是单字符代换密码的扩展,通过将多个明文字符映射为多个密文字符增加加密复杂度。以双字符代换为例,详细阐述了加密和解密过程,以及填充规则。并提供了一个简单的C++程序实现双字符代换密码,展示了如何对字符串'hello'进行加密和解密。这种方法在一定程度上隐藏了原文信息,提高了安全性。
摘要由CSDN通过智能技术生成

一、什么是多字符代换密码

所谓多字符代换密码,其实是单表代换的一个简单改进,也就是把原来的代换表,由单个字符到单个字符的映射,变成了多个字符到多个字符的映射。比如,原来在单表代换中,明文字符a用b代换,字符b用d代换,故ab,加密成bd;而多字符代换则是一次加密多个明文字符,比如ab,直接用另一个字符对ac代替,形成密文ac。
多字符代换密码的典型例子是Playfair密码。
本质上来说,多字符代换并没有引入新的东西,只是把原来代换表变大了,也就是扩充了明文字符集。不妨设一个明文字符集为{a,b,c},那么其对应的双字符代换就是把明文字符集扩充为{aa,ab,ac,bb,ba,bc,cc,ca,cb}。但是,由于明文字符集增大了,其代换表的可能个数就增大了,增加了破译密码的难度。
但是,我们在设计多字符代换的时候,需要考虑一个填充的问题。比如双字符代换密码,那么,一次加密必须要加密两个字符。也就是说,明文字符的个数必须是偶数。比如要加密bad,我们需要在加一个字符填充成4个字符长度的明文,再加密,如再bad后填充x,即变成了badx,这样就可以加密了。相应的,在解密的时候要把填充的字符去掉。
一种可能的填充方式是,填充一般不会在明文中出现的字符,这样,可以便于去除填充的字符。比如在26个英文字符的明文字符集中,填充数字,并设定相应的代换规则,在解密的时候遇到了数字,便知道是填充的,可以丢弃。

二、一个简单的双字符代换密码

考虑明文字符集为26个小写英文字母,代换的长度为2,也就是双字符代换。填充的字符为z(假定z在正常明文中不会出现)。

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<time.h>
using namespace std;
//generate the random table,table[0] means pair characters aa,
//table[1] means ab, table[2] means ac and so on.
vector<int> genTable(){
	srand((unsigned)time(NULL));
	vector<bool> flag(676);
	vector<int> table(676);
	bool finish=false;
	int temp;
	int i=0;
	while(i<676){
		temp=rand()%676;
		if(flag[temp]){
			continue;
		}
		table[i++]=temp;
		flag[temp]=true;
	}
	return table;
}
//encrypt function, 
string encrypt(string message, vector<int> &table){
	int f1,s1,f2,s2;
	if(message.size()%2==1){
		message.push_back('z');
	}
	for(int i=0;i<message.size();i+=2){
		f1=message[i]-'a';
		s1=message[i+1]-'a';
		f2=table[f1*26+s1]/26;
		s2=table[f1*26+s1]%26;
		message[i]=f2+'a';
		message[i+1]=s2+'a';
	}
	return message;
}
//decipher
string decipher(string cipher, vector<int> &table){
	//generator r_table
	vector<int> r_table(676);
	for(int i=0;i<table.size();i++){
		r_table[table[i]]=i;
	}
	int f1,s1,f2,s2;
	for(int i=0;i<cipher.size();i+=2){
		f1=cipher[i]-'a';
		s1=cipher[i+1]-'a';
		f2=r_table[f1*26+s1]/26;
		s2=r_table[f1*26+s1]%26;
		cipher[i]=f2+'a';
		cipher[i+1]=s2+'a';
	}
	if(cipher.back()=='z'){
		cipher.pop_back();
	} 
	return cipher;
}
int main(){
	vector<int> table;
	table=genTable();
	string message,cipher;
	cout<<"Please input message:";
	cin>>message;
	cipher=encrypt(message,table);
	cout<<"The ciphertext is:"<<cipher<<endl;
	cout<<"After deciphering:"<<decipher(cipher,table)<<endl;
}

比如下面对hello加密,可以看到相同字母l在密文中不再相同,对明文的信息有一定的掩盖作用。

Please input message:hello
The ciphertext is:yifuqe
After deciphering:hello

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值