密码学:古典密码.代替密码.仿射密码加密与解密 (广义欧几里得除法)

乘法密码和加法密码结合构成仿射密码,放射密码函数为

f(ai)=bi=aj (i,j为下角标)

j=i*k1+k0 mod n 只对大写英文加密n为26

其中:要求 (k1,n)=1, 0<=k0<n,且不允许同时有k1=1和k0=0

代码解释:

在输入时密文为字符串,通过ASCII码进行加减A对应的ASCII码把英文字母对应为0~25

在找k1时用广义欧几里得除法得到1~25之内与26互素的数字放在p数组里面,用于密钥k1的选择

代码:

cpp 复制代码
#include <stdio.h>
#include <string.h>
int Findp(int p[],int n)
{
    int top=0,flag=1;
    if (n%2)
        flag=0;     //如果n为偶数,偶数必然不和n互素
    {
        for (int i=1;i<n;)//利用广义欧几里得除法找1~n之内与n互素的数
        {
            int j1=n,j0=i,r=i;
            while(r!=0)
            {
               do{
                    j1-=j0;
                    r=j1;
                }while(r>=j0);
                j1=j0;
                j0=r;
            }
            if(j1==1)
                p[top++]=i;
            if(!flag)
                i+=2;
            else
                i++;
        }
    }
    return top;
}

int main()
{
    char M[9999],C[9999];
    printf("请输入明文字符(大写英文字母,回车结束)\n");
    fgets(M,9999,stdin);
    int k1,k0,n=26;
    printf("请输入密钥k1 k0(中间空格分隔,k1=1和K0=0不能同时),");
    int p[26];
    int num=Findp(p,n);
    printf("k1可取值为");
    for (int i=0;i<num;i++)
        printf("%d ",p[i]);
    printf("\n");
    scanf("%d%d",&k1,&k0);
    printf("密文\n");
    int end=strlen(M),top=0;
    for (int i=0;i<end-1;i++)
    {
        if(M[i]==' ')
            C[i]=' ';
        else
            C[i]=((M[i]-65)*k1+k0)%n+65;
    }
    for (int i=0;i<end-1;i++)
    {
            printf("%c",C[i]);
    }
    printf("\n解密\n");
    for (int i=0;i<end-1;i++)
    {
        if (C[i]==' ')
            printf("%c",C[i]);
        else
        {
            int m=(C[i]-65-k0);//不能用char类型!!!!m超过100多变为负数
            //while(-25%25)不执行 所以不能小于0
            while(m%k1 || m<0) //需要先加26 什么时候模K1为0停止
                m+=26;
        //因为选K1时互素,所以这里即使后面也有模K1为0的 除k1后再mod26是一样的结果
            printf("%c",m/k1+65);
        }
    }
}
相关推荐
小年糕是糕手36 分钟前
【数据结构】算法复杂度
c语言·开发语言·数据结构·学习·算法·leetcode·排序算法
明天会有多晴朗1 小时前
深度剖析 C++ 之内存管理篇
c语言·开发语言·c++
potato_may1 小时前
C语言第3讲:分支和循环(上)—— 程序的“决策”与“重复”之旅
c语言·开发语言
智者知已应修善业3 小时前
【51单片机32个灯,第一次亮1,2。第二次亮2,3。第三次亮3,4。。。。】2023-2-10
c语言·经验分享·笔记·嵌入式硬件·51单片机
无限进步_5 小时前
【C语言】寻找数组中唯一不重复的元素
c语言·开发语言·算法
JuneXcy5 小时前
C语言易错点大总结
c语言·嵌入式硬件·算法
迎風吹頭髮6 小时前
UNIX下C语言编程与实践39-UNIX 定时器:alarm 函数与 setitimer 函数的使用与对比
服务器·c语言·unix
egoist20237 小时前
[linux仓库]System V 进程通信详解:System V消息队列、信号量
linux·c语言·消息队列·pv·信号量
Archie_IT7 小时前
「深入浅出」嵌入式八股文—P2 内存篇
c语言·开发语言·数据结构·数据库·c++·算法
XCOSnTh9 小时前
单片机入门的相关工具XCOSnTh
c语言·单片机·嵌入式硬件·xcosnth·单片机入门