C语言实现仿射密码实验
废话不多说直接上代码
#include<stdio.h>
int main(){
int p,k1,k2;//仿射密钥 c=k1*m+k2 mod p 古典密码p=26
int N = 1000;
char message[N+1];
printf("Input the message to process:");
//以回车(换行)作为字符串读取的结束,默认遇空格、回车、跳格键结束。
scanf("%[^\n]",message);
printf("\nThe message/plaintext is:%s",message);
int length=strlen(message);
char cipher[length],decipher[length];
int type;//加解密类型
printf("\n请选择加解密方式: 0--加密,1--解密:");
scanf("%d",&type);
if(type==0)
{
printf("对输入的文本进行加密处理:\n");
printf("\nPlease input the three affine cipher parameters:k1,k2,p,以逗号分隔:");
//读取数值时,默认以空格分隔,如需逗号则在%d后面指定格式:scanf("%d,%d",&k1,&k2);
scanf("%d,%d,%d",&k1,&k2,&p);
printf("\nThe input keys are: k1=%d , k2= %d, p= %d \n",k1,k2,p);
//getchar()在scanf()后,可以吸收回车符,以便输入下一个字符/串。特别是在后续需输入含空格的字符串时
getchar();
int i ;
for(i=0; i<length;i++)
{
if(message[i]>='a'&&message[i]<='z')
cipher[i]=(k1*(message[i]-'a')+k2)%p+'a';
else
if(message[i]>='A'&&message[i]<='Z')
cipher[i]=(k1*(message[i]-'A')+k2)%p+'A';
else{
cipher[i]=message[i];
}
}
cipher[length]='\n';//字符串时及时添加结束标志以防额外增加数组长度。
printf("消息加密前后对比如下:\n");
printf("The Input Text is: %s.\n",message);
printf("The Output Text is: %s.\n",cipher);
file_write(cipher);//打印生成一个加密后的文本文件作为存储以方便后续的解密过程
}
else{
printf("文本将进行解密处理:\n");
int s,t;
int reverse;//k1的逆元
int i;
printf("\nPlease input the three affine cipher parameters:k1,k2,p,以逗号分隔:");
//读取数值时,默认以空格分隔,如需逗号则在%d后面指定格式:scanf("%d,%d",&k1,&k2);
scanf("%d,%d,%d",&k1,&k2,&p);
printf("\nThe input keys are: k1=%d , k2= %d, p= %d \n",k1,k2,p);
reverse=ojld(k1,p,s,t);
for(i=0; i<length;i++){
if(message[i]>='a'&&message[i]<='z')
{
decipher[i]=(reverse*((cipher[i]-'a')-k2) )%p+'a';
}
else
if(message[i]>='A'&&message[i]<='Z')
{
decipher[i]=(reverse*((cipher[i]-'A')-k2))%p+'A';
}
else
decipher[i]=message[i];
}
printf("经过解密内容为:%s.\n",decipher);
}
}
void file_write(char*cipher)
{
int i;
FILE *outfile;
outfile = fopen("加密.txt","w");
if(outfile==NULL)
{
printf("Can't open the file!\n");
}
fprintf(outfile,"%s",cipher);
fclose(outfile);
}
int gcd(int a,int b){//欧几里得算法
if(a<b){
int t=b;
b=a;
a=t;
}
while(a%b!=0){
int r=a%b;
a=b;
b=r;
r=a%b;
}
return b;
}
int ojld(int r0,int r1,int s,int t){//欧几里得扩展算法
int R0=r0,R1=r1;
if(r0==0||r1==0){
printf("ERROR:One of the two input numbers is zero.\n");
return 0;
}
int q=0,r2=0,s0=1,s1=0,s2=0,t0=0,t1=1,t2=0;
while(r1!=0){
q=r0/r1;
r2=r0%r1;
s2=s0-s1*q;//计算新s
t2=t0-t1*q;//计算新t
//更新r0,r1,s0,s1,t0,t1
r0=r1;r1=r2;
s0=s1;s1=s2;
t0=t1;t1=t2;//保存s2,t2的值,以备下次使用
}
if(r0==1){
s0=(R1+(s0%R1))%R1;
t0=(R0+(t0%R0))%R0;
//printf("Afterwards [P+(x mod P)]mod P:s0=%d,t0=%d.\n",s0,t0);
printf("k1的逆元:%d.\n",s0);
s=s0;
t=t0;
//printf("THE GCD is:%d UNEQUAL TO 1,NO INVERSE EXITS.\n",r0);
return s0;
}
}