仿射密码加密解密(C语言)

仿射密码是一种古典移位密码,其算法设计时用到的数学基础是模运算和同余方程。它是一个字母对一个字母的加密密码。定义明文空间 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)Z26Z26:gcd(a,26)=1} 对于 x ∈ P , y ∈ C , k = ( a , b ) ∈ K x\in P, y\in C,k=(a,b)\in K xP,yC,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)=a1(yb)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 <stdio.h>
#include <stdlib.h>
#include<string.h>

//求逆  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语言的指针,学的时候感觉难,现在看还是难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T1009∞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值