📄 希尔.cpp
字号:
#include"stdio.h"
#include"stdlib.h"
#include"iostream.h"
#include"math.h"
void HOpen(char *file)
{
FILE *fp;
char ch;
int i=0;
if(!(fp=fopen(file,"r")))
{
printf("打开文件%s失败",file);
exit(0);
}
ch=fgetc(fp);
while(ch!='#')
{
printf("%c",ch);
ch=fgetc(fp);
}
fclose(fp);
}
void Rewrite(int &k)
{
char ch;
int *a,ai=0,f=0;
FILE *fp;
if(!(fp=fopen("HillRect.txt","w")))
{
printf("打开文件HillRect失败");
exit(0);
}
printf("输入新矩阵的阶k:\n");
scanf("%d",&k);
getchar();//消掉回车键
a=(int *)malloc((k*k+1)*sizeof(int));
a[ai]=0;
printf("请输入新矩阵,k=%d(以'#'号结束):\n",k);
do
{
do
{
ch=getchar();
if(ch>='0' && ch<='9')
{
a[ai]=a[ai]*10+ch-'0';
f=1;
continue;
}
if(f)
{
if(k==1 && ((ai>1) || (ch!='#')))
{//在此只是为了查错,保证能跳出循环并觉察到错就行
while(ch!='\n')ch=getchar();
ch='#';
ai=0;
break;
}
ai++;
a[ai]=0;
f=0;
}
}while(ch!='\n' && ch!='#');
}while(ch!='#' && !(ai%k));
if(ai==k*k)
for(int j=0;j<k*k;)
{
fprintf(fp,"%d ",a[j]);
j++;
if(!(j%4))fputc('\n',fp);
}
fputc('#',fp);
fclose(fp);
if(ai!=k*k)
{
printf("输入出错,请重输.!!!\n");
Rewrite(k);
}
}
int Qiuyu(int data1,int data2)
{//求余数以判断是否有逆矩阵
int d1,d2;
if(data1<0)data1=-data1;
if(data2<0)data2=-data2;
d1=data1/data2;
d2=data1%data2;
if(d2)
return Qiuyu(data2,d2);
else if(data2==1)return 1;
else return 0;
}
void Read(int *head,int k)
{//假定在矩阵中是正确
FILE *fp;
if(!(fp=fopen("HillRect.txt","r")))
{
printf("打开文件HillRect.txt失败");
exit(0);
}
int i=0,j,a;
char b;
while(i<k)
{
j=0;
while(j<k)
{
a=0;
b=fgetc(fp);
if(!(b>='0' && b<='9') )continue;
while(b>='0' && b<='9')
{
a=a*10+(b-'0');
b=fgetc(fp);
}
head[i*k+j]=a;
j++;
}
i++;
}
fclose(fp);
}
//求行列式或余子式的值
int Value(int *head,int k)
{
int ii,jj,si,sj,svalue=0,*sub;
if(k==2)
{
svalue=head[0]*head[3]-head[1]*head[2];
return svalue;
}
int j,value,s;
s=k-1;
sub=(int *)malloc((s*s)*sizeof(int));
for(j=0;j<k;j++)
{
for(ii=1,si=0;ii<k;ii++)
{
for(jj=0,sj=0;jj<k;jj++)
{
if(jj==j)continue;
sub[s*si+sj]=head[k*ii+jj];
sj++;
}
si++;
}
value=Value(sub,k-1);
if(j%2)value=-value;
svalue+=head[j]*value;
}
return svalue;
}
int YuZiShi(int *head,int k,int i,int j)
{//求得各余子式
int ii,jj,si,sj,s,svalue,*sub;
s=k-1;
sub=(int *)malloc((s*s)*sizeof(int));
if(k==2)
{
int hi,hj;
hi=k-i-1;
hj=k-j-1;
return head[k*hi+hj];
}
for(ii=0,si=0;ii<k;ii++)
{
if(ii==i)continue;
for(jj=0,sj=0;jj<k;jj++)
{
if(jj==j)continue;
sub[s*si+sj]=head[k*ii+jj];
sj++;
}
si++;
}
svalue=Value(sub,k-1);
return svalue;
}
int NiYuan(int value,int n)
{//逆元
int i,v=0;
if(value<0)value=-value;
for(i=1;i<n;i++)
{
v+=value;
if(v%n==1)break;
}
return i;
}
void HillEncode(int *head,int *c,int k,int N)
{
int i=0,j,*m;
char ch;
FILE *fp;
if(!(fp=fopen("Hillmiwen.txt","w")))
{
printf("打开文件Hillmiwen失败");
exit(0);
}
m=(int *)malloc(k*sizeof(int));
printf("请输入待加密的字符串,k=%d\n",k);
while(i<k)
{
ch=getchar();
if(ch>'a' && ch<'z')ch=ch-32;
if(ch<'A' || ch>'Z')continue;
m[i]=ch-'A';
c[i++]=0;
}
for(i=0;i<k;i++)
{
for(j=0;j<k;j++)
c[i]+=head[k*i+j]*m[j];
c[i]=c[i]%N;
ch='A'+c[i];
fputc(ch,fp);
}
fputc('#',fp);
fclose(fp);
}
void HillDecode(int *ni,int *c,int k,int N)
{
int i,j,*m;
char ch;
m=(int *)malloc(k*sizeof(int));
for(i=0;i<k;i++)
{
m[i]=0;
for(j=0;j<k;j++)
m[i]+=ni[k*i+j]*c[j];
m[i]=m[i]%N;
ch='A'+m[i];
printf("%c",ch);
}
}
void main()
{
int devition,value,ny,yzs;
int *head,*ni,*c;
int choice,k=4,N=26,i,j,f=1,rw=1;//k为矩阵的阶,若修改矩阵则应改变k
printf("\t****Hill 加密算法****");
printf("\n\t1.输入希尔矩阵");
printf("\n\t2.希尔加密");
printf("\n\t3.查看密文");
printf("\n\t4.希尔解密");
printf("\n\t0.退出");
while(f)
{
printf("\n\t请选择:");
scanf("%d",&choice);
if(rw && choice!=1)
{
head=(int *)malloc((k*k)*sizeof(int));
ni=(int *)malloc((k*k)*sizeof(int));
c=(int *)malloc(k*sizeof(int));
Read(head,k);
value=Value(head,k);
devition=Qiuyu(N,value);
ny=NiYuan(value,N);
if(value<0)ny=-ny;
for(i=0;i<k;i++)
for(j=0;j<k;j++)
{
yzs=YuZiShi(head,k,j,i);
if((i+j)%2)yzs=-yzs;
yzs=yzs*ny;
ni[k*i+j]=yzs%26;
if(yzs<0)ni[k*i+j]=26+ni[k*i+j];
}
}
rw=0;
switch(choice)
{
case 0:f=0;break;
case 1:Rewrite(k);f=1;rw=1;break;
case 2:HillEncode(head,c,k,N);f=2;break;
case 3:if(f==2)HOpen("Hillmiwen.txt");
else printf("还没加密!!");break;
case 4:if(f==2)HillDecode(ni,c,k,N);
else printf("还没加密!!");break;
default:printf("选择出错!!");break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -