密码学之凯撒密码(C语言)

代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <ctype.h>

#define N 1000

//加密
void encrypt();

//解密
void decrypt();

//穷举解密
void decryptAll();

/*
 * main()函数负责生成选择菜单并供用户选择
 */
int main() {
    int select;
    while (1) {     //循环控制加解密完成后再次进入模式选择界面
        printf("----------**模式选择**----------\n");
        printf("1:加密\n");
        printf("2:解密\n");
        printf("3:暴力破解\n");
        printf("输入其他:退出\n");
        printf("--------------***---------------\n");
        printf("输入序号:");
        scanf("%d", &select);
        if (select == 1)
            encrypt();      //选1加密
        else if (select == 2)
            decrypt();      //选2解密
        else if (select == 3)
            decryptAll();       //选3穷举所有明文
        else        //其他情况直接退出
            return 0;
    }
}

/*
 * 输入并判断密钥格式,符合条件就返回密钥
 * key要在1~26之间
 */
int key() {
    char k[N];      //将key定义成字符串而不是int,避免输入字符时报错
    printf("输入密钥(1~26):");
    gets(k);        //获取字符串
    while (1) {
        if (atoi(k) > 0 && atoi(k) <= 26)      //atoi()是将字符串转为数字
            break;
        printf("格式错误,输入密钥(1~26):");
        gets(k);
    }
    return atoi(k);
}
/*
 * 解密时的字母转换
 * 参数为:密文,明文,密钥
 * 作用是根据密钥将密文转换为明文
 */
void change(char plaintext[], char ciphertext[], int k) {
    for (int i = 0; i < strlen(ciphertext); i++) {
        if (islower(ciphertext[i]))
            plaintext[i] =
                    //(ciphertext[i] - 'a' - k) < 0时,则自身+26,保证a往前移又回到了z
                    ((ciphertext[i] - 'a' - k) > 0 ? (ciphertext[i] - 'a' - k) : ((ciphertext[i] - 'a' - k) + 26)) %
                    26 + 'a';
        else if (isupper(ciphertext[i]))
            plaintext[i] =
                    //解释同上
                    ((ciphertext[i] - 'A' - k) > 0 ? (ciphertext[i] - 'A' - k) : ((ciphertext[i] - 'A' - k) + 26)) %
                    26 + 'A';
        else
            plaintext[i] = ciphertext[i];       //遇到非字母则不转换
    }
}

/*
 * 加密操作
 * @返回值:密文
 * @参数:明文、密钥
 */
void encrypt() {
    char plaintext[N] = {}, ciphertext[N] = {};
    int k;
    getchar();//清除缓存中遗留的回车
    printf("输入明文:");
    gets(plaintext);
    k = key();
    for (int i = 0; i < strlen(plaintext); i++) {
        if (islower(plaintext[i]))      //如果是小写
            ciphertext[i] = (plaintext[i] - 'a' + k) % 26 + 'a';
        else if (isupper(plaintext[i]))     //如果是大写
            ciphertext[i] = (plaintext[i] - 'A' + k) % 26 + 'A';
        else
            ciphertext[i] = plaintext[i];       //遇到非字母则不转换
    }
    printf("密文是:");
    puts(ciphertext);
}

/*
 * 解密操作
 * @返回值:明文
 * @参数:密文、密钥
 */
void decrypt() {
    char plaintext[N] = {}, ciphertext[N] = {};
    int k;
    getchar();//清除缓存
    printf("输入密文:");
    gets(ciphertext);
    k = key();      //调用key()函数输入并检验密钥格式
    change(plaintext, ciphertext, k);//调用change()函数处理密文转换成明文
    printf("明文是:");
    puts(plaintext);
}

/*
 * 穷举
 * @返回值:密文
 * @参数:明文
 */
void decryptAll() {
    char plaintext[N] = {}, ciphertext[N] = {};
    getchar();//清除缓存
    printf("输入密文:");
    gets(ciphertext);
    for (int k = 1; k <= 26; ++k) {     //密钥为1~26时,穷举出每个密钥对应的明文
        change(plaintext, ciphertext, k);   //调用change()函数处理密文转换成明文
        printf("当key = %d时,明文是:", k);
        puts(plaintext);
    }
}
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页