当前位置: 首页 > article >正文

C语言实现简单凯撒密码算法

  • **实验2:传统密码技术 【实验目的】 通过本次实训内容,学习常见的传统密码技术,通过编程实现简单代替密码中的移位密码算法,加深对传统密码技术的了解,为深入学习密码学奠定基础。
  • 【技能要求】
    • 分析简单代替密码中的移位密码算法的功能需求,详细设计实现简单代替密码中的移位密码算法的数据结构和流程,给出测试用例和测试步骤,得出测试和结论。
    • 简单代替密码中的移位密码算法必须提供加密和解密两个接口:int encrypt()和int decrypt()。当加密或者解密成功时,返回CRYPT_OK,失败时返回CRYPT_ERROR。
  • 【实验内容】
    • 利用自己熟悉的程序设计语言,实现简单代替密码中的移位密码。要求程序给出源代码以及相应的注释,实验结果截图。**

根据实验要求,我们将实现一个简单的移位密码(也称为凯撒密码)算法。这种加密方法是通过将字母表中的每个字母向前或向后移动固定数量的位置来进行加密和解密的。例如,如果移位数为3,那么A会被替换为D,B会变成E,以此类推。

规范代码演示

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

#define CRYPT_OK 0
#define CRYPT_ERROR -1

// 加密函数
int encrypt(char *text, int shift) {
    if (shift < 0 || shift > 25) {
        return CRYPT_ERROR; // 移位数必须在0到25之间
    }

    for (int i = 0; text[i] != '\0'; ++i) {
        if (isalpha(text[i])) { // 只处理字母字符
            char base = isupper(text[i]) ? 'A' : 'a';
            text[i] = ((text[i] - base + shift) % 26) + base; // 计算新的字符位置
        }
    }
    return CRYPT_OK;
}

// 解密函数
int decrypt(char *text, int shift) {
    return encrypt(text, 26 - (shift % 26)); // 解密就是使用相反方向的移位
}

int main() {
    char text[100];
    int shift;

    // 获取用户输入的文本
    printf("请输入要加密的文本: ");
    fgets(text, sizeof(text), stdin);
    text[strcspn(text, "\n")] = 0; // 去掉换行符

    // 获取移位数
    printf("请输入移位数(0-25): ");
    if (scanf("%d", &shift) != 1 || shift < 0 || shift > 25) {
        printf("无效的移位数。\n");
        return CRYPT_ERROR;
    }

    // 加密
    if (encrypt(text, shift) == CRYPT_OK) {
        printf("加密后的文本: %s\n", text);
    } else {
        printf("加密失败。\n");
        return CRYPT_ERROR;
    }

    // 解密
    if (decrypt(text, shift) == CRYPT_OK) {
        printf("解密后的文本: %s\n", text);
    } else {
        printf("解密失败。\n");
        return CRYPT_ERROR;
    }

    return 0;
}

测试用例和步骤

  1. 运行程序。
  2. 输入要加密的文本,例如 “Hello, World!”。
  3. 输入一个有效的移位数,例如 3。
  4. 检查输出的加密文本是否正确,例如对于移位3,应得到 “Khoor, Zruog!”。
  5. 检查解密后的文本是否与原始文本相同。

运行截图

请添加图片描述请添加图片描述

注意事项

  • 程序假设输入文本不会超过99个字符。
  • 程序只处理英文字符,非字母字符保持不变。
  • 使用fgets来读取包含空格的字符串,而strcspn用于去除末尾的换行符。
  • decrypt函数实际上调用了encrypt函数,但使用了相反的移位数来实现解密。

这个程序可以作为一个基础示例,你可以根据需要添加更多的功能或改进错误处理逻辑。

核心代码加密逻辑

移位密码(凯撒密码)的核心思路。

移位密码的基本概念

移位密码是一种简单的替换加密方法。它通过将字母表中的每个字母向前或向后移动固定数量的位置来进行加密。例如,如果移位数是3,那么A会被替换成D,B会替换成E,以此类推。对于字母表的末尾,Z会绕回到A继续计算。

实现步骤

  1. 遍历字符串

    • 你需要逐个检查输入文本中的每一个字符。
    • 如果遇到非字母字符(如空格、标点符号等),则保持不变。
    • 如果遇到字母字符,则进行移位操作。
  2. 处理大小写

    • 英文有大写字母和小写字母,所以需要分别处理。
    • 大写字母从’A’到’Z’,小写字母从’a’到’z’。
    • 为了方便处理,我们可以先确定当前字母是大写还是小写,然后基于相应的基准字母(大写是’A’,小写是’a’)进行移位。
  3. 计算新的字符位置

    • 计算当前字母与基准字母之间的距离。
    • 加上移位数。
    • 使用模运算(% 26)来确保结果在0到25之间。
    • 最后再加上基准字母,得到新的字符。

代码详解

下面是对核心代码的进一步简化解释:

for (int i = 0; text[i] != '\0'; ++i) {
    if (isalpha(text[i])) { // 只处理字母字符
        char base = isupper(text[i]) ? 'A' : 'a';
        text[i] = ((text[i] - base + shift) % 26) + base; // 计算新的字符位置
    }
}
逐行解释
  1. 遍历字符串

    for (int i = 0; text[i] != '\0'; ++i) {
    
    • 这一行代码使用for循环遍历字符串text中的每个字符,直到遇到字符串结束符\0
  2. 只处理字母字符

    if (isalpha(text[i])) {
    
    • isalpha函数检查当前字符是否为字母。如果是字母,进入花括号内的代码块;如果不是,跳过该字符。
  3. 确定基准字母

    char base = isupper(text[i]) ? 'A' : 'a';
    
    • isupper函数检查当前字符是否为大写字母。
    • 如果是大写字母,base设置为'A';如果是小写字母,base设置为'a'
    • 这样可以确保我们对大写和小写字母分别进行正确的移位。
  4. 计算新的字符位置

    text[i] = ((text[i] - base + shift) % 26) + base;
    
    • text[i] - base:计算当前字符与基准字母之间的距离。例如,如果text[i]'D'base'A',那么'D' - 'A'等于3。
    • + shift:加上移位数。例如,如果shift是3,那么3 + 3等于6。
    • % 26:取模26,以确保结果在0到25之间。这样可以处理移位超过字母表长度的情况。
    • + base:再加上基准字母base,得到最终的新字符。例如,如果base'A',那么6 + 'A'就是'G'
    • 最终,text[i]被替换为新的字符。

示例

假设text是 “Hello”,shift是3:

  • 对于H(ASCII 72),base'A'(ASCII 65),72 - 65 + 3等于10,10 % 26等于10,10 + 65等于75,所以H变成K
  • 对于e(ASCII 101),base'a'(ASCII 97),101 - 97 + 3等于7,7 % 26等于7,7 + 97等于104,所以e变成h
  • 其他字符类似处理。

最终,“Hello"加密后会变成"Khoor”。

这个过程对于解密也是类似的,只是移位的方向相反。

附加

关于isalpha, iswalpha

在这里插入图片描述

在这里插入图片描述

  1. isalpha(c)

    • 返回值:isalpha()函数返回一个非零值(通常为1),如果参数c位于范围’A-Z’或’a-z’内。这意味着c是一个英文字母。
    • 参数:c是要测试的整数值。
    • 依赖性:isalpha()的结果取决于当前locale(区域设置)的LC_CTYPE类别设置。可以通过setlocale()函数更改locale设置。
  2. iswalpha(c)

    • 返回值:iswalpha()函数仅在满足以下条件的情况下返回非零值:c是一个宽字符,且iswupper()iswlower()也为真。也就是说,c是一个由实现定义的集合中的任何宽字符,对于这些字符,iswcntrl(), iswdigit(), ispunct(), 或 isspace()都不为真。
    • 参数:c是要测试的宽字符。
    • 依赖性:iswalpha()的结果独立于locale,不受locale影响。

这两个函数都返回0,如果参数c不满足测试条件。


http://www.kler.cn/news/319081.html

相关文章:

  • springboot使用minio(8.5.11)
  • 某易易盾验证码逆向
  • vue3 选择字体的颜色,使用vue3-colorpicker来选择颜色
  • Spring Boot集成LiteFlow使用详解
  • 【可变模板参数】
  • DS18B20温度传感器模块
  • Day29笔记-Python操作pdfPython发送邮件
  • 广州C++信奥赛老师解一本通题 1389:亲戚
  • llamafactory0.9.0微调qwen2.5
  • Docker 教程:如何查看容器的最后 300 行实时日志
  • Hi.Events —— 您的全方位活动管理与票务平台
  • 几乎跪着读完这本Transformer经典神书,震撼到爆!!
  • 什么是自然语言处理
  • set的使用
  • 插入、更新与删除MySQL记录
  • 【Linux】快速上手shell脚本(适合初学者)
  • 最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本)
  • 精益六西格玛管理实践中如何保证小组成员的稳定性?
  • Spring定时任务 - @Scheduled注解详解
  • IDEA相关设置总结
  • (11)iptables-仅开放指定ip访问指定端口
  • 飞腾平台perf工具PMU事件集成指南
  • 一分钟掌握 Java15 新特性
  • StringReader 使用 JAXB自动将 XML 数据映射到 Java 对象
  • Nginx 限流实战教程和技巧
  • Vue3 Day7-全局组件、指令以及pinia
  • uniapp app 端通过webview引入外部 js , webview 与 app 通信
  • spring-boot-maven-plugin插件打包和java -jar命令执行原理
  • [研发工具箱] 系列3.机电类常用的分类网站
  • Android开发拍身份证带人像框和国徽框效果