仿射密码(C语言实现)
简介
仿射密码是一种表单代换密码,字母表的每个字母相应的值使用一个简单的数学函数对应一个数值,再把对应数值转换成字母。
加解密公式
加密函数:
Y =(AX+B)%26
解密函数:
X =(A的逆元)*(Y-B)%26
来个官方一点的
加密函数:E(x) = (ax + b) (mod m),其中 a与b互质,m是编码系统中字母的个数(通常都是26)。
解密函数:D(x) = (x - b) (mod m),其中 是 a 在群的乘法逆元。
C语言实现
#include <stdio.h>
#include <string.h>
//加密
int encrypt(char *text,char *result,int k1,int k2)
{
int i,z=0;
int l = strlen(text); //获取明文的长度
for(i=0;i<l;i++)
{
//判断大小写
if (text[i] >= 'A' && text[i] <= 'Z'){
result[z]=(k1*(text[i]-'A')+k2)%26+'A';
} else if (text[i] >= 'a' && text[i] <= 'z'){
result[z]=(k1*(text[i]-'a')+k2)%26+'a';
} else{ //判断是否是空格
result[z] = text[i];
}
z++;
}
return 0;
}
//解密
int decrypt(char *text,char *result,int k3,int k2)
{
int i,z=0;
int l = strlen(text); //获取明文的长度
for(i=0;i<l;i++)
{
//判断大小写
if (text[i] >= 'A' && text[i] <= 'Z'){
result[z]=(k3*((text[i]-'A')-k2))%26+'A';
if(k3*((text[i]-'A')-k2) < 0){
result[z] = result[z] + 26;
}
} else if (text[i] >= 'a' && text[i] <= 'z'){
result[z]=(k3*((text[i]-'a')-k2))%26+'a';
if(k3*((text[i]-'a')-k2) < 0){ //处理负数
result[z] = result[z] + 26;
}
} else{ //判断是否是空格
result[z] = text[i];
}
z++;
}
return 0;
}
int main()
{
char text[50]="";
char result[50]="";
int k1,k2,k3;
int type;
/**欢迎**/
printf("--------欢迎使用仿射密码-----------\n");
printf("请填写明文或者密文\n");
scanf("%[^\n]",text);
printf("请选择加密方式,输入1加密,输入2解密\n");
scanf("%d",&type);
if(type == 1){
/**加密**/
printf("请输入密钥k1\n");
scanf("%d",&k1);
printf("请输入密钥k2\n");
scanf("%d",&k2);
encrypt(text,result,k1,k2);
printf("明文%s的密文为:%s\n",text,result);
}else if(type == 2){
/**解密**/
printf("请输入密钥k1的逆元\n");
scanf("%d",&k3);
printf("请输入密钥k2\n");
scanf("%d",&k2);
decrypt(text,result,k3,k2);
printf("密文%s的明文为:%s\n",text,result);
}
return 0;
}
验证
加密
明文AFFINECIPHER,k1=5,k2=8
解密
密文IHHWVCSWFRCP,k1=5的逆元21,k2=8
缺陷
逆元没有写上去,等我理解了再来,这里给出一张逆元表
后面再来优化