多表代换

四、实验原理:
多表代换密码首先将明文分为由n个字母构成的分组,对每个分组的加密为:
在这里插入图片描述
其中(A,B)是密钥,A是n*n的可逆矩阵,满足
在这里插入图片描述
对密文分组的解密为:
在这里插入图片描述
五、实验目的:
1、熟悉多表代换密码算法;
2、掌握密码算法中参数选取、密钥生成、加密和解密的基本流程。
六、实验内容:
实现n=3的多表代换密码体制,能够随机生成密钥对输入的英文字母信息进行加密或正确解密。
七、实验器材(设备、元器件):
学生每人一台PC,安装Windows 7操作系统及VC++/Python开发环境。
八、实验步骤:
1.密钥生成
(1)随机生成3ⅹ3可逆矩阵A,
在这里插入图片描述

计算其行列式并模去26,若其行列式等于零或与26不互素,则重新生成矩阵。矩阵生成后,计算其在模26下的逆矩阵。
(2)生成3维向量B。
(3)保存A,A模逆,B作为秘密密钥。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

九、实验数据及结果分析:
(1)实验参考代码:

 #include<stdio.h>
    #include<string.h>
    #include <stdlib.h>
    #include<math.h>
    
    char ALPHABET[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','3','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    
    int gcd(int a,int b){
    	return b==0?a:gcd(b,a%b);
    }
    
    	int A[3][3] = { {0,0},{0,0} ,{0,0}};
    int get_A(){
    
    	int p,dt;
    	int i=0;
    	int j=0;
    
    do{
    	A[0][0]=rand()%26;
        A[0][1]=rand()%26;
        A[0][2]=rand()%26;
        A[1][0]=rand()%26;
        A[1][1]=rand()%26;
        A[1][2]=rand()%26;
        A[2][0]=rand()%26;
        A[2][1]=rand()%26;
        A[2][2]=rand()%26;
    	dt = -1;
        for(p=1; dt < 0; p++)
        {
            dt = ((A[0][0] * A[1][1] * A[2][2] + A[0][1] * A[1][2]*A[2][0] +A[1][0]*A[2][1]*A[0][2]-A[1][1]*A[2][0]*A[0][2]-A[0][1]*A[1][0]*A[2][2]-A[0][0]*A[1][2]*A[2][1]
    			+ 26 * p)%26); //行列式的值 
        }
    }while(gcd(dt,26)!=1);
    for(i=0;i<3;i++){
    	for(j=0;j<3;j++){
    		printf("%d ",A[i][j]);}
    		printf("\n");
    }
    
    
    
    }
    
    int get_B(){
    	int i=0;
    	int j=0;
    	int B[3]={3,4,5};
    	printf("输出B的值:\n"); 
    
    	for(j=0;i<3;i++){
    	 printf("%d\n",B[i]);
    	}
    
    
    }
    
    
    char cleartext[60]={0};
    char ciphertext[60]={0};
    int encode(char cleartext[60],int A[3][3],int B[3]){
    	
    	int temp[60]={0};//存放转换成数字的明文
    	 int i,j;
    	 int flag;
    	int len;
    	int n;
    	int m[3]={0};
    	
    	for(i=0;i<3;i++){	
    	  for(j=0;j<3;j++){
    		printf("%d ",A[i][j]);}
    		printf("\n");
    }
    	
    	
    	printf("请输入明文:");
    	scanf("%s",cleartext);
        len=strlen(cleartext);
        for(i=0; i<len; i++)
            {
                if(cleartext[i] >= 'A' && cleartext[i] <= 'Z')
                {
                    temp[i] = cleartext[i] + 32;
                }
    
                temp[i] = cleartext[i] - 'a';
            }
            
            
            if(len % 3 == 1)
            {
                cleartext[len] = cleartext[len-1];
                len = strlen(cleartext);
                flag=1;
                
            }
            
        
        
        	for(i=0; i<len; i+=3)
            {   
               
                
    
                
               m[0] = (A[0][0] * temp[i]+A[0][1]*temp[i]+A[0][2]*temp[i] +B[0] ) % 26;
               m[1] = (A[1][0] * temp[i+1]+A[1][1]*temp[i+1]+A[1][2]*temp[i+1] +B[1] ) % 26;
               m[2] = (A[2][0] * temp[i+2]+A[2][1]*temp[i+2]+A[2][2]*temp[i+2] +B[2] ) % 26;          
            
    
                temp[i] = m[0];
                temp[i+1] = m[1];
                temp[i+2]=m[2];            //printf("密文是%c%c",T2[i],T2[i+1]);
            }	
            
          	
           
     if(flag == 1)
            {
                len = len - 1;
            }
      
      	
    	
    	for(i=0; i<len; i++){
    	
    
            {
                cleartext[i] = temp[i] + 'a';
                printf("%c", cleartext[i]);
            }
            printf("\n");}
     
    
    	}
    //int decode()
    int exgcd(int a, int b, int &x, int &y){
    	int d = a;
    	if(b != 0){
    		d = exgcd(b, a %b, y, x);
    		y -= (a / b) * x;
    	}
    	else{
    		x = 1;	y = 0;
    	}
    } 
    
    int verse(int a){
        int x, y, n = 26;
        exgcd(a, n, x, y);
        return (n + x % n) % n;
    }
    int A_verse[3][3];
    void Averse(int A[3][3],int A_verse[3][3] ){
        int det_A;
        int i,j;
    	det_A = ((A[0][0] * A[1][1] * A[2][2] + A[0][1] * A[1][2]*A[2][0] +A[1][0]*A[2][1]*A[0][2]-A[1][1]*A[2][0]*A[0][2]-A[0][1]*A[1][0]*A[2][2]-A[0][0]*A[1][2]*A[2][1]
    			+ 26 * 1024)%26); //行列式的值 
        
    	int det_A_verse = verse(det_A);
    	//int A_p[3][3];
    	printf("1/det(A) = %d\n", det_A_verse);
    	A_verse[0][0] = det_A_verse * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) % 26;
    	A_verse[0][1] = det_A_verse * (A[0][1] * A[2][2] - A[0][2] * A[2][1]) * (- 1) % 26;
    	A_verse[0][2] = det_A_verse * (A[0][1] * A[1][2] - A[0][2] * A[1][1]) % 26;
    	A_verse[1][0] = det_A_verse * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) * (- 1) % 26;
    	A_verse[1][1] = det_A_verse * (A[0][0] * A[2][2] - A[0][2] * A[2][0]) % 26;
    	A_verse[1][2] = det_A_verse * (A[0][0] * A[1][2] - A[0][2] * A[1][0]) * (- 1) % 26;
    	A_verse[2][0] = det_A_verse * (A[1][0] * A[2][1] - A[1][1] * A[2][0]) % 26;
    	A_verse[2][1] = det_A_verse * (A[0][0] * A[2][1] - A[0][1] * A[2][0]) * (- 1) % 26;
    	A_verse[2][2] = det_A_verse * (A[0][0] * A[1][1] - A[0][1] * A[1][0]) % 26;
    	
    	for(int i = 0; i < 3; i ++){
    		for(int j = 0; j < 3; j ++){
    			A_verse[i][j] = (A_verse[i][j] + 26) % 26;
    		}
    	}
    	for(int i = 0; i < 3; i ++){
    		for(int j = 0; j < 3; j ++){
    			printf("%d ",A_verse[i][j]);
    		}
    		printf("\n");
    	}
    }
    int decode(char cleartext[60],int A_verse[3][3],int B[3]){
    	int temp[60]={0};//存储转换后的密文 
    	int len,flag;
    	int i;
    	int m[3]={0};
    	printf("请输入密文:");
    	scanf("%s",ciphertext);
        len=strlen(ciphertext);
        for(i=0; i<len; i++)
            {
                if(ciphertext[i] >= 'A' && ciphertext[i] <= 'Z')
                {
                    temp[i] =ciphertext[i] + 32;
                }
    
                temp[i] = ciphertext[i] - 'a';
            }
            
        if(len % 3 == 1)
            {
                ciphertext[len] = ciphertext[len-1];
                len = strlen(ciphertext);
                flag=1;
                
            }
            
        
        
        	for(i=0; i<len; i+=3)
            {   
               
                
    
                
               m[0] = (A_verse[0][0] *(temp[i]-B[0])+A_verse[0][1]*(temp[i]-B[0])+A_verse[0][2]*(temp[i]-B[0] )) % 26;
               m[1] = (A_verse[1][0] *(temp[i+1]-B[1])+A_verse[1][1]*(temp[i+1]-B[1])+A_verse[1][2]*(temp[i+1]-B[1] )) % 26;
               m[2] = (A_verse[2][0] *(temp[i+2]-B[2])+A_verse[2][1]*(temp[i+2]-B[2])+A_verse[2][2]*(temp[i+2]-B[2] )) % 26;       
            
    
                temp[i] = m[0];
                temp[i+1] = m[1];
                temp[i+2]=m[2];            //printf("密文是%c%c",T2[i],T2[i+1]);
            }	
            
          	
           
     if(flag == 1)
            {
                len = len - 1;
            }
      
      	
    	
    	for(i=0; i<len; i++){
    	
    
            {
                ciphertext[i] = temp[i] + 'a';
                printf("%c", ciphertext[i]);
            }
            printf("\n");}
     
    
    	}
        
            
    	

int main(){
	//int i,j;

	int B[3]={3,4,5};
	get_A();
	


	get_B();	Averse(A,A_verse);
	
	char choose;
	printf("加密输入a,解密输入b\n"); 
	scanf("%c",&choose);
	if(choose=='a'){
	encode(cleartext,A,B);
	}
	else if(choose=='b'){
		decode(ciphertext,A_verse,B);
	}
	

	
	
	
}

猜你喜欢

转载自blog.csdn.net/llllliuchang/article/details/89605487