c语言实现多表代换密码算法及求逆元

密文及明文默认长度为4的倍数
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int ex_gcd(int a,int b,int &x,int &y)       //扩展欧几里得 
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int r=ex_gcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
    return r;
}

int re_yuan(int a,int b)                    //求a的逆元x 
{
    int d,x,y;
    d=ex_gcd(a,b,x,y);
    return (x%b+b)%b;
}

void IuputAre_A(int A[][4])                 //A与A^-1的输入
{
    for (int i = 0; i < 4;i++)
        for (int j = 0; j < 4; j++)
            scanf("%d", &A[i][j]);
}

void InputB(int B[])                        //B输入
{
    for (int i = 0; i < 4;i++)
        scanf("%d", &B[i]);
}

bool checkA(int A[][4],int re_A[][4])                               //验证密钥的正确性(即A*A^-1=E)
{
    for (int i = 0; i < 4;i++)
    {
        for (int j = 0; j < 4;j++)
        {
            int sum = A[i][0]*re_A[0][j]+A[i][1]*re_A[1][j]+A[i][2]*re_A[2][j]+A[i][3]*re_A[3][j];
            //printf("
%f %f %f %f %f %f %f %f 
",A[i][0],re_A[0][j],A[i][1],re_A[1][j],A[i][2],re_A[2][j],A[i][3],re_A[3][j]);
            //printf("sum is %f
", sum);
            //printf("sum is %d
", sum%26);
            if(i==j)
            {
                if(sum%26!=1)
                    return 0;
            }else
            {
                if(sum%26!=0)
                    return 0;
            }
        }
    }
    return 1;
}

void Encrypt(int A[][4],char Enstring[],int StrLen,int B[])         //加密函数,参数为 A,要加密的明文,明文长度,B
{
    char M[StrLen/4][4];
    for (int i = 0; i < StrLen;i++)
    {
        Enstring[i] -= 65;
    }
    for (int i = 0; i < StrLen / 4; i++)           //求Ci
    {
        for (int j = 0; j < 4; j++)
        {
            M[i][j] = (Enstring[i * 4] * A[j][0] + Enstring[i * 4 + 1] * A[j][1] + Enstring[i * 4 + 2] * A[j][2] + Enstring[i * 4 + 3] * A[j][3] + B[j]) % 26;
        }
    }
    for (int i = 0; i < StrLen/4;i++)                                //数字对应字母
    {
        for(int j=0;j<4;j++)
        {
            if(M[i][j]<0)
				M[i][j] += 26;
            Enstring[i*4+j] = M[i][j]+65;
        }
    }

}

void Decrypt(int re_A[][4],char Destring[],int StrLen,int B[])      //解密函数,参数为 A^-1,要解密的密文,密文长度,B
{
    char M[StrLen/4][4];
    for (int i = 0; i < StrLen;i++)
    {
        Destring[i] -= 65;
    }
    for (int i = 0; i < StrLen / 4;i++)                            //英文字母和十进制数对应
    {
        for (int j = 0; j < 4;j++)
        {
             Destring[i * 4 + j] -= B[j];
        }
    }
    for (int i = 0; i < StrLen / 4;i++)                            //求Mi
    {
        for (int j = 0; j < 4;j++)
        {
            M[i][j] = (Destring[i * 4] * re_A[j][0] + Destring[i * 4 + 1] * re_A[j][1] + Destring[i * 4 + 2] * re_A[j][2] + Destring[i * 4 + 3] * re_A[j][3] ) % 26;
        }
    }
    for (int i = 0; i < StrLen/4;i++)                                //数字对应字母
    {
        for(int j=0;j<4;j++)
        {
            if(M[i][j]<0)
				M[i][j] += 26;
            Destring[i*4+j] = M[i][j]+65;
        }
    }

}

int main(){
    int A[4][4], B[4],re_A[4][4];
{                                                      //A、B、A^-1的输入
    printf("请输入加密密钥密钥(A,B)和解密密钥A^-1 (分组为4):
A:");
    IuputAre_A(A);                  //A的输入
    printf("
B:");
    InputB(B);                      //B的输入
    printf("
A^-1:");
    IuputAre_A(re_A);               //A^-1的输入
}
    while(1){                                         //验证密钥的正确性(即A*A^-1=E),若不正确则提示再次输入
        if(!checkA(A,re_A)){
            system("cls");
            printf("请输入正确的A和A^-1!
A:");
            IuputAre_A(A);
            printf("A^-1:");
            IuputAre_A(re_A);
            continue;
        }
        break;
    }
    while(1){
    printf("
请输入功能序号:
0.加密
1.解密
2.求逆元
3.退出程序
");
    int FunType;
    scanf("%d", &FunType);
    if(FunType==3)
    {
        return 0;
    }
    else if(FunType==0)                               //功能0.加密
    {                             
        char EnString[1000];
        printf("请输入待加密明文(长度为四的倍数):");
        scanf("%s", EnString);
        int StrLen = strlen(EnString);
        Encrypt(A, EnString,  StrLen,  B);
        printf("加密后的密文是:%s
", EnString);
    }
    else if(FunType==1)                               //功能1.解密
    {
        char DeString[1000];
        printf("请输入待解密密文(长度为四的倍数):");
        scanf("%s", DeString);
        int StrLen = strlen(DeString);
        if(StrLen%4!=0)                              //对长度不是4的倍数的明文的处理,
        {
            for (int i = 0; i < (StrLen % 4); i++)
            {
                DeString[StrLen + i] = ' ';
            }
            StrLen += 4 - StrLen % 4;
            DeString[StrLen] = 0;                     //字符串以0结尾
        }
        Decrypt(re_A, DeString,  StrLen,  B);
        printf("解密后的明文是:%s
", DeString);
    }
    else if(FunType==2)                               //功能2.求逆元
    {
        int a, m;
        printf("a:");
        scanf("%d", &a);
        printf("m:");
        scanf("%d", &m);
        printf("
%d模%d 的逆元为:%d
", a, m, re_yuan(a, m));
    }
    else
    {
        printf("请输入正确的功能编号!");
    }
    } 
}
原文地址:https://www.cnblogs.com/pluie/p/13621846.html