/******************
C=AM+B
M=A^(-1)(C-B)
******************/
#include<iostream>
#include<string>
#include<math.h>
#include<iomanip>
using namespace std;
int GetdetA(int **a, int n)
{
int **cofactor = new int*[n];//余子式
for(int i=0; i<n; ++i)
cofactor[i] = new int[n];
int sum = 0;
int p=0, q=0;
if(n == 1) return a[0][0];
for(int i=0; i<n; ++i){
for(int j=0; j<n-1; ++j){
if(j < i) p=0;
else p=1;
for(int k=0; k<n-1; ++k)
cofactor[j][k] = a[j+p][k+1];
}
if(i % 2 == 0) q=1;
else q=-1;
sum = sum+a[i][0]*q*GetdetA(cofactor, n-1);
}
for(int i=0; i<n; ++i)
delete []cofactor[i];
delete []cofactor;
return sum;
}
//获取Aij余子式
int GetAij(int **a, int row, int col, int n)
{
//余子式
int **cofactor=new int*[n-1];
for(int i=0; i<n-1; ++i)
cofactor[i]=new int[n-1];
int r=0, c=0;
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
if(row!=i&&col!=j){
cofactor[r][c] = a[i][j];
++c;
}
if(c == n-1){
c=0, ++r;
}
}
}
int detc = GetdetA(cofactor, n-1);
delete []cofactor;
return detc;
}
//逆矩阵
void AdjugateMatrix(int **a,int **adm,int n)
{
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
if((i+j)%2==0)
adm[i][j] = GetAij(a, j, i, n);
else
adm[i][j] = -GetAij(a, j, i, n);
}
}
}
int InverseElem(int x,int y,int m)
{
int a=1,b=x,n=y;
while(n){
if(n&1)
a=(a*b)%m;
b=(b*b)%m;
n>>=1;
}
return a;
}
void InverseMatrix(int **a, int **ina, int n)
{
int deta = GetdetA(a, n);
if(deta>=0) deta%=26;
else deta=deta%26+26;
int indeta = InverseElem(deta, 11, 26);
cout<<"det(A)= "<<indeta<<endl;
int **adm = new int*[n];
for(int i=0;i<n;++i)
adm[i]=new int[n];
AdjugateMatrix(a, adm, n);
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
if(adm[i][j]>=0) adm[i][j]%=26;
else adm[i][j]=adm[i][j]%26+26;
}
}
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
ina[i][j] = (adm[i][j]*indeta) % 26;
}
}
delete []adm;
cout<<"Inverse Matrix (mod 26)"<<endl;
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j)
cout<<ina[i][j]<<" ";
cout<<endl;
}
}
int * MatrixAdd(int *x, int *y, int n)
{
int *andmatrix = new int[n];
for(int i=0; i<n; ++i)
andmatrix[i] = (x[i] + y[i]) % 26;
return andmatrix;
}
int * MatrixSub(int *x, int *y, int n)
{
int *submatrix = new int[n];
for(int i=0; i<n; ++i)
submatrix[i] = (x[i] - y[i] + 26) % 26;
return submatrix;
}
int * MatrixMul(int **a, int *y, int n)
{
int *mulmatrix = new int[n];
for(int i=0; i<n; ++i)
mulmatrix[i] = 0;
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
mulmatrix[i] = (mulmatrix[i] + a[i][j] * y[j]) % 26;
}
}
return mulmatrix;
}
string Encryption(string m, int **a, int *b, int n)
{
string c = m;
int index = 0;
int *part = new int[n];
int *finpart = new int[n];
int len = m.length();
if(len%4!=0){
cout << len << " Do not ...." << endl;
return m;
}
for(int i=0; i<len;){
for(int j=0; j<n; ++j){
if(m[i] >= 'a' && m[i] <= 'z')
part[j] = m[i] - 'a';
if(m[i] >= 'A' && m[i] <= 'Z')
part[j] = m[i] - 'A';
cout << setw(4) << part[j];
++i;
}
cout << " ==>> ";
part = MatrixMul(a, part, n);
finpart = MatrixAdd(part, b, n);
for(int k=0; k<n; ++k){
if(m[i-n+k] >= 'a' && m[i-n+k] <= 'z')
c[index++] = finpart[k] + 'a';
if(m[i-n+k] >= 'A' && m[i-n+k] <= 'Z')
c[index++] = finpart[k] + 'A';
cout << setw(4) << finpart[k];
}
cout << endl;
}
delete []part;
delete []finpart;
return c;
}
string Decryption(string c, int **ina, int *b, int n)
{
string m = c;
int index = 0;
int *part = new int[n];
int *finpart = new int[n];
int len = c.length();
if(len%4!=0){
cout << len << " Do not ...." << endl;
return c;
}
for(int i=0; i<len;){
for(int j=0; j<n; ++j){
if(c[i] >= 'a' && c[i] <= 'z')
part[j] = c[i] - 'a';
if(c[i] >= 'A' && c[i] <= 'Z')
part[j] = c[i] - 'A';
cout << setw(4) << part[j];
++i;
}
cout << " ==>> ";
part = MatrixSub(part, b, n);
finpart = MatrixMul(ina, part, n);
for(int k=0; k<n; ++k){
if(c[i-n+k] >= 'a' && c[i-n+k] <= 'z')
m[index++] = finpart[k] + 'a';
if(c[i-n+k] >= 'A' && c[i-n+k] <= 'Z')
m[index++] = finpart[k] + 'A';
cout << setw(4) << finpart[k];
}
cout << endl;
}
delete []part;
delete []finpart;
return m;
}
int main()
{
while(1){
cout << "Please enter text" <<endl;
string text;
cin >> text;
cout << "Please enter the group" <<endl;
int n;
cin >> n;
cout << "Please enter the key(A)" <<endl;
int **a = new int*[n];
for(int i=0; i<n; ++i)
a[i] = new int[n];
int **ina = new int*[n];
for(int i=0; i<n; ++i)
ina[i] = new int[n];
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
cin >> a[i][j];
cout << "Please enter the key(B)" <<endl;
int *b = new int[n];
for(int i=0; i<n; ++i)
cin >> b[i];
cout << "Encryption(1)?" << "Decryption(2)?" << "Exit(5)" <<endl;
int selectnum;
cin >> selectnum;
switch(selectnum){
case 1 :
cout << Encryption(text, a, b, n) << endl;;
break;
case 2 :
InverseMatrix(a, ina, n);
cout << Decryption(text, ina, b, n) << endl;
break;
default :
return 0;
}
}
return 0;
}
多表变换
最新推荐文章于 2024-02-20 20:38:43 发布