仿射密码是一种古典移位密码,其算法设计时用到的数学基础是模运算和同余方程。它是一个字母对一个字母的加密密码。定义明文空间 P = Z 26 P={\rm Z}_{26} P=Z26 ,密文空间 C = Z 26 C={\rm Z}_{26} C=Z26 ,秘钥空间为 K = { ( a , b ) ∈ Z 26 ⋅ Z 26 : g c d ( a , 26 ) = 1 } K=\lbrace (a,b)\in {\rm Z}_{26} \cdot {\rm Z}_{26}:gcd(a,26)=1 \rbrace K={(a,b)∈Z26⋅Z26:gcd(a,26)=1} 对于 x ∈ P , y ∈ C , k = ( a , b ) ∈ K x\in P, y\in C,k=(a,b)\in K x∈P,y∈C,k=(a,b)∈K 定义加密函数 e k ( x ) = a x + b m o d 26 {\rm e}_k(x)=ax+b\mod \ 26 ek(x)=ax+bmod 26
,定义解密函数 d k ( x ) = a − 1 ( y − b ) m o d 26 ) {\rm d}_k(x)=a^{-1}(y-b)\mod \ 26) dk(x)=a−1(y−b)mod 26)
,其中是a在群的乘法逆元(求a在群的乘法逆元)。当a=1时,仿射密码,弱化为凯撒密码。
1.加密过程: text为要加密的明文,password为加密后的密文
//加密
char* encode(char* text,int addkey,int mulkey)
{
char* password=NULL;//空指针
//开辟空间
password=(char*)malloc(10*sizeof(char));
for(int i=0;i<strlen(text);i++)
{
int code=text[i]-'a';
password[i]=(code*mulkey+addkey)%26+'a';
}
return password;
}
2.求逆过程: 拓展欧几里得算法
//求逆 b%m的逆
int extendedeuclid(int m,int b)
{
int a1,a2,a3;
int b1,b2,b3;
int t1,t2,t3;
a1=1;a2=0;a3=m;
b1=0;b2=1;b3=b;
while(1)
{
if(b3==0) return 0;
if(b3==1)
{
if(b2<0) b2=m+b2;
return b2;
}
int q=a3/b3;
t1=a1-q*b1;t2=a2-q*b2;t3=a3-q*b3;
a1=b1;a2=b2;a3=b3;
b1=t1;b2=t2;b3=t3;
}
return 0;
}
3.解密过程: password是要解密的密文,text是得到的解密后的明文。
//解密
char* decode(char* password,int addkey,int mulkey)
{
char* text=NULL;
text=(char*)malloc(10*sizeof(char));
for(int i=0;i<strlen(password);i++)
{
int code=password[i]-'a';
text[i]=( (code-addkey+ 26) * extendedeuclid(26,mulkey) )% 26 + 'a';
}
return text;
}
4.完整代码:
#include
#include
#include
//求逆 b%m的逆
int extendedeuclid(int m,int b)
{
int a1,a2,a3;
int b1,b2,b3;
int t1,t2,t3;
a1=1;a2=0;a3=m;
b1=0;b2=1;b3=b;
while(1)
{
if(b3==0) return 0;
if(b3==1)
{
if(b2<0) b2=m+b2;
return b2;
}
int q=a3/b3;
t1=a1-q*b1;t2=a2-q*b2;t3=a3-q*b3;
a1=b1;a2=b2;a3=b3;
b1=t1;b2=t2;b3=t3;
}
return 0;
}
//加密
char* encode(char* text,int addkey,int mulkey)
{
char* password=NULL;//空指针
//开辟空间
password=(char*)malloc(10*sizeof(char));
for(int i=0;i<strlen(text);i++)
{
int code=text[i]-'a';
password[i]=(code*mulkey+addkey)%26+'a';
}
return password;
}
//解密
char* decode(char* password,int addkey,int mulkey)
{
char* text=NULL;
text=(char*)malloc(10*sizeof(char));
for(int i=0;i<strlen(password);i++)
{
int code=password[i]-'a';
text[i]=( (code-addkey+ 26) * extendedeuclid(26,mulkey) )% 26 + 'a';
}
return text;
}
int main()
{
char text[200];
printf("请输入明文:");
scanf("%s",text);
int k,b;
printf("请输入k,b的值:");
scanf("%d%d",&k,&b);
char *p=NULL;
char *q=NULL;
p=q=(char*)malloc(10*sizeof(char));
p=encode(text,k,b);
q=decode(p,k,b);
printf("加密后的密文:%s\n",p);
printf("解密后的明文:%s",q);
free(p);free(q);
return 0;
}
Cmd Markdown 公式指导手册
复习了一下C语言的指针,学的时候感觉难,现在看还是难。