【密码学】多表代换

解析都在代码里

/*
     _/_/_/                                                    
   _/          _/_/_/    _/_/      _/_/_/    _/_/_/  _/  _/_/   
  _/        _/    _/  _/_/_/_/  _/_/      _/    _/  _/_/        
 _/        _/    _/  _/            _/_/  _/    _/  _/           
  _/_/_/    _/_/_/    _/_/_/  _/_/_/      _/_/_/  _/         
                                                                      */
#include <iostream>
#include <string>
#define N 4   // 定义分组数 
using namespace std;

string multiplication(char* str,int a[N][N]); // 适用于 N*N 与 N*N 的矩阵相乘 
class cryption{
	string plaintext;// 明文
	string encrypt;// 加密文 
	string decrypt;// 解密文 
public: 
	cryption(string a)
	: plaintext(a){}
	string out_en(){return this->encrypt;}  
	string out_de(){return this->decrypt;} // 对密文的赋值,用于解密 
	void input_en(string en){this->encrypt=en;}
	void encryption(int a[N][N],int b[N]);  // 加密函数 
	void decryption(int aa[N][N],int b[N]);  // 解密函数 
friend string multiplication(char* str,int a[N][N]);
}; 
void cryption::encryption(int a[N][N],int b[N])
{
	string ssr;
	string str=this->plaintext;
	int len=str.size();
	
	for(int i=0;i<len/N;i++){
		ssr+=multiplication(&(str[N*i]),a); // 矩阵乘法 a*str[N*i:N*i+N]=ssr[N*i:N*i+N]
	}
	for(int j=0;j<len;j++)ssr[j]=(ssr[j]+b[j%N])%128; // (ssr[j]+b[j%N])mod 128 ->ASCII码 
	this->encrypt=ssr; 
}
void cryption::decryption(int aa[N][N],int b[N])
{
	string ssr;
	string str=this->encrypt;
	int len=str.size();

	for(int i=0;i<len;i++)str[i]=(str[i]-b[i%N])%128; // (str[i]-b[i%N])mod 128 
	for(int j=0;j<len/N;j++){
		ssr+=multiplication(&(str[N*j]),aa);  // 矩阵乘法 a*str[N*j:N*j+N]=ssr[N*i:N*i+N]
	}
	this->decrypt=ssr;
} 
void is_right(int a[N][N],int aa[N][N]); // 判断密钥正确性 
void is_right(int a[N][N],int aa[N][N])
{
	int b[N][N]={0};
	for(int i=0;i<N;i++){
		for(int j=0;j<N;j++)
		{
			for(int k=0;k<N;k++) 
				b[i][j]+=a[i][k]*aa[k][j]; // 矩阵乘法 
		}
	}
	int flag=1; 
	for(int i=0;i<N;i++){
		for(int j=0;j<N;j++){
			cout<<b[i][j]%128<<" ";
			if(b[i][j]!=1&&i==j)flag=0;
			if(b[i][j]!=0&&i!=j)flag=0;
		}	
		cout<<endl;
	}
	if(flag)cout<<"密钥正确"<<endl;
	else{
		cout<<"密钥错误"<<endl;
		exit(1);
	}
}
string multiplication(char* str,int a[N][N])
{
	string s="";
	char c=0;
	for(int i=0;i<N;i++){
		for(int j=0;j<N;j++)
			c=(c+a[i][j]*str[j]+12800)%128; // 矩阵乘法 
		s+=c;
		c=0;
	}
	return s;
}

int main()
{
//  输入部分	
	cout<<"请输入加密密钥 a:"<<endl; 
	int a[N][N],b[N],aa[N][N];
	for(int i=0;i<N;i++){
		for(int j=0;j<N;j++)
			cin>>a[i][j];
	}
	cout<<"请输入加密密钥 b:"<<endl; 
	for(int i=0;i<N;i++)
		cin>>b[i];
	cout<<"请输入解密密钥 a:"<<endl; 
	for(int i=0;i<N;i++){
		for(int j=0;j<N;j++)
			cin>>aa[i][j];
	}

//0 0 1 2 0 0 3 5 2 -1 0 0 -5 3 0 0
//1 21 8 17
//0 0 3 1 0 0 5 2 -5 2 0 0 3 -1 0 0
//	int a[N][N]={0,0,1,2,0,0,3,5,2,-1,0,0,-5,3,0,0};
//	int b[N]={1,21,8,17};
//	int aa[N][N]={0,0,3,1,0,0,5,2,-5,2,0,0,3,-1,0,0}; // 题目所给密钥不适用于所有编码,且有错误 
	
	string str;
	is_right(a,aa);
	getchar();
	getline(cin,str);
	int len=str.size();
	if(len%N){
		for(int k=0;k<N-len%N;k++)
			str+=" "; // 长度不是N的倍数补空格 
	}
	cryption test(str);
	test.encryption(a,b);
	test.decryption(aa,b);
	cout<<test.out_en()<<endl;
	cout<<test.out_de()<<endl;
	return 0;
}	




贴个原始版本来丢人

#include <iostream>
#include <string>
// 标点符号支持 " " "," "." 
using namespace std;
void is_right(int a[4][4],int aa[4][4]);
string encryption(string str,int a[4][4],int b[4]);
string decryption(string str,int aa[4][4],int b[4]);
string multiplication(char* str,int a[4][4]);

string multiplication(char* str,int a[4][4])
{
	string s="abcd";
	for(int i=0;i<4;i++){
		s[i]='A'+(a[i][0]*(str[0]-'A')+a[i][1]*(str[1]-'A')+a[i][2]*(str[2]-'A')+a[i][3]*(str[3]-'A')+2900)%29;
	}
	return s;
}
void is_right(int a[4][4],int aa[4][4])
{
	int b[4][4];
	int sum=0,flag=1;
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++)
		{
			b[i][j]=a[i][1]*aa[1][j]+a[i][2]*aa[2][j]+a[i][3]*aa[3][j]+a[i][0]*aa[0][j];
		}
	}
	int i,j;
	for(i=0;i<4;i++){
		for(j=0;j<4;j++)
		{
			cout<<b[i][j]%29<<" ";
		}
		cout<<endl;
	}
}

string encryption(string str,int a[4][4],int b[4])
{
	string ss="";
	int len=str.size();
	int sum=0; 
	
	for(int i=0;i<len/4;i++){
		ss+=multiplication(&(str[4*i]),a);  
	}
	for(int i=0;i<len;i++)ss[i]=(ss[i]+b[i%4]-'A')%29 +'A';
	return ss; 
}

string decryption(string str,int aa[4][4],int b[4])
{
	string ss="";
	int len=str.size();
	int sum=0; 
	for(int i=0;i<len;i++)str[i]=(str[i]-b[i%4]-'A'+29)%29+'A';
	for(int i=0;i<len/4;i++){
		ss+=multiplication(&(str[4*i]),aa);  
	}
	for(int k=0;k<len;k++){
		if(ss[k]=='[') ss[k]=' ';
		else if(ss[k]=='/') ss[k]=',';
		else if(ss[k]==']') ss[k]='.';
	}
	return ss; 
}

int main()
{
	int n=4,i,j;
	int a[4][4]={0,0,1,2,0,0,3,5,2,-1,0,0,-5,3,0,0};

	int b[4]={1,21,8,17};
	int aa[4][4]={0,0,3,1,0,0,5,2,-5,2,0,0,3,-1,0,0};
	
//	for(i=0;i<n;i++){
//		for(j=0;j<n;j++)
//			cin>>a[i][j];
//	}
//	for(i=0;i<n;i++)
//		cin>>b[i];
//	for(i=0;i<n;i++){
//		for(j=0;j<n;j++)
//			cin>>aa[i][j];
//	}
	is_right(a,aa);
	
	string str,encrypt,decrypt;
	getline(cin,str);
	int len=str.size();
	if(len%4){
		for(int k=0;k<4-len%4;k++)
			str+=" ";
	}
	for(int k=0;k<len;k++){
		if(str[k]==' ') str[k]='[';
		else if(str[k]==',') str[k]='/';
		else if(str[k]=='.') str[k]=']';
	}
	encrypt=encryption(str,a,b);
	cout<<encrypt<<endl;
	decrypt=decryption(encrypt,aa,b);
	cout<<decrypt<<endl;
	return 0;
}	



  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
多表代换密码是一种基于替换的密码算法,它将明文字符替换为密文字符,从而实现加密。在多表代换密码中,通常采用多个替换表来进行加密,以增加密码的复杂度和安全性。 下面是一个简单的用 C 语言实现多表代换密码的示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_TABLES 26 #define TABLE_SIZE 26 // 生成随机的替换表 void generate_tables(char tables[MAX_TABLES][TABLE_SIZE+1]) { int i, j; for (i = 0; i < MAX_TABLES; i++) { char c = 'a' + i; // 生成替换表的第一个字符 tables[i][0] = c; for (j = 1; j < TABLE_SIZE; j++) { tables[i][j] = c + j; if (tables[i][j] > 'z') { tables[i][j] -= 26; } } tables[i][TABLE_SIZE] = '\0'; } } // 加密函数 char* encrypt(const char* plain, const char tables[MAX_TABLES][TABLE_SIZE+1]) { int len = strlen(plain); char* cipher = (char*) malloc(len+1); int i, j; for (i = 0; i < len; i++) { char c = plain[i]; if (c >= 'a' && c <= 'z') { int table = c - 'a'; // 根据明文字符选择替换表 j = rand() % TABLE_SIZE; // 随机选择替换字符 cipher[i] = tables[table][j]; } else { cipher[i] = c; } } cipher[len] = '\0'; return cipher; } // 解密函数 char* decrypt(const char* cipher, const char tables[MAX_TABLES][TABLE_SIZE+1]) { int len = strlen(cipher); char* plain = (char*) malloc(len+1); int i, j; for (i = 0; i < len; i++) { char c = cipher[i]; if (c >= 'a' && c <= 'z') { int table = c - 'a'; // 根据密文字符选择替换表 j = strcspn(tables[table], &cipher[i]); // 查找替换字符在替换表中的位置 plain[i] = 'a' + j; // 明文字符为替换字符在替换表中的位置加上 'a' } else { plain[i] = c; } } plain[len] = '\0'; return plain; } int main() { char tables[MAX_TABLES][TABLE_SIZE+1]; generate_tables(tables); const char* plain = "hello world"; printf("Plain text: %s\n", plain); char* cipher = encrypt(plain, tables); printf("Cipher text: %s\n", cipher); char* decrypted = decrypt(cipher, tables); printf("Decrypted text: %s\n", decrypted); free(cipher); free(decrypted); return 0; } ``` 在这个示例中,我们首先生成了 26 个大小为 26 的随机替换表,然后使用 `encrypt()` 函数对明文进行加密,使用 `decrypt()` 函数对密文进行解密。在加密过程中,对于明文中的每个小字母,我们根据它在字母表中的位置选择一个替换表,然后随机选择一个替换字符进行替换。在解密过程中,对于密文中的每个小字母,我们根据它所代表的替换表和替换字符进行逆替换,得到明文字符。 需要注意的是,这个示例中的多表代换密码算法并不是非常安全,因为替换表是固定的,而且对于明文中的每个小字母都使用了不同的替换表,这使得攻击者可以通过分析密文中的字母频率来破译密码。实际应用中,应该使用更加复杂的算法来生成替换表,以及使用更加灵活的方法来选择替换字符和替换表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

赤城封雪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值