//仿射变换主要是乘法与加法变换的结合
//C=a*m+k mod 26 加密
//M=a^-1(c-k)mod 26 解密
#include <iostream>
#include<fstream>
#include<string.h>
#include<stdlib.h>
#define MAX 10000
using namespace std;
int gcd(int a, int b) /*辗转相除法求a,b的最大公因数*/
{
int k = 0;
do
{
k = a%b;
a = b;
b = k;
}
while(k!=0);
return a;
}
int Ni(int a, int b) /*求a相对于b的逆元*/
{
int i = 0;
while(a*(++i)%b!=1); //a*i=1 mod b
return i;
}
void Fshe(char c[MAX],char m) /*仿射密码*/
{
int length, i=0, ka=0, kb=0, tmp;
do
{
cout<<"ka 和 kb : ";
cin>>ka>>kb;
getchar();
if(gcd(ka,94)!=1)
{
cout<<"密钥输入有误,请重新输入!\n";
//如果输入的秘钥与模数94不互素则需要重新输入
}
}
while(gcd(ka,94)!=1&&m=='d'); //用于验证秘钥的合法性
length = strlen(c);
if(m=='e')
{
for(i=0; i<length; i++) //加密算法c[i]=ka*m[i]+kb mod 94
{
c[i] = (ka*(c[i]-32)+kb)%94+32; //字符ASCII从32----126
}
}
if(m=='d')
{
for(i=0; i<length; i++) //解密算法 m[i]=Ni*(c[i]-kb)mod 94 {
{
c[i] =Ni(ka,94)*((c[i]-32)-kb); //解密需要使用乘法逆元
}
}
}
int main()
{
ifstream fin("d:/mingwen.txt",ios::in); //明文存储的文件
ofstream fout("d:/miwen.txt",ios::out); //新建文件存储密文
ifstream fin1("d:/miwen.txt",ios::in); //需要打开密文文件
ofstream fout1("d:/jiemi.txt",ios::out); // 存储解密后的数据
char str[MAX],str1[MAX];
if(!fin) //依次打开文件
{
cout<<"can't open ! please creat the file (d:/mingwen.txt) ! \n";
exit(1);
}
if(!fin1)
{
cout<<"can't open fin1!\n";
exit(1);
}
if(!fout)
{
cout<<"can't open fout!\n";
exit(1);
}
if(!fout1)
{
cout<<"can't open fout1!\n";
exit(1);
}
char m;
cout<<"请选择加密(e)解密(d)操作:"; //增加操作性选择加密或解密操作
cin>>m;
switch(m)
{
case 'e':
fin.getline(str,MAX);
Fshe(str,m); //加密操作
//cout<<str<<endl; //输出加密后的字符
fout<<str;
cout<<"明文已加密!\n";
break;
case 'd':
fin1.getline(str1,MAX);
Fshe(str1,m); //解密操作
// cout<<str<<endl; //输出解密后的字符
fout1<<str1;
cout<<"密文已解密!\n";
break;
default:
break;
}
fin.close(); //文件操作完后关闭文件
fout.close();
fin1.close();
fout1.close();
return 0;
}