四、实验原理:
多表代换密码首先将明文分为由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);
}
}