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.xdnf.cn/news/150625.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Java特性】多态详解——对象类型转换与 instanceof 关键字的运用

多态是指不同类的对象在调用同一个方法时所呈现出的多种不同行为。通常来说&#xff0c;在一个类中定义的属性和方法被其他类继承或重写后&#xff0c;当把子类对象直接赋值给父类引用变量时&#xff0c;相同引用类型的变量调用同一个方法所呈现出的多种不同形态。多态不仅解决…

数据结构与算法学习day23-回溯算法-递增子序列

一、递增子序列 1.题目 491. 非递减子序列 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xf…

深入理解端口、端口号及FTP的基本工作原理

FTP是TCP/IP的一种具体应用&#xff0c;FTP工作在OSI模型的第七层&#xff0c;TCP模型的第四层上&#xff0c;即应用层&#xff0c;FTP使用的是传输层的TCP传输而不是UDP&#xff0c;这样FTP客户在和服务器建立连接前就要经过一个被广为熟知的“三次握手”的过程&#xff0c;其…

路面坑洼与道路缺陷目标检测数据集——(路面裂缝目标检测数据集——含10000多张图像 数据集已按照yolo txt格式标注好)

路面坑洼&#xff0c;道路缺陷&#xff0c;路面裂缝目标检测数据集 共包含10000多张图像&#xff0c;包含纵向裂缝、纵向拼接缝、错误标签、横向裂缝、横向拼接缝、龟裂、坑洞、十字路口模糊、白线模糊、井盖十个标签&#xff0c;依次对应D00到D50&#xff0c; 其中D01、D0W0、…

3D全息投影简易制作:用矿泉水瓶制作反射镜面、剪映制作3D投影视频

参看视频&#xff1a;https://www.bilibili.com/video/BV1HW411H7B3/?vd_source34d74181abefaf9d8141bbf0d485cde7 3D全息投影&#xff1a;主要是反射衍射原理 1、用矿泉水瓶制作反射镜面 参看&#xff1a;https://www.iesdouyin.com/share/video/7005120687492828416 2、剪映…

鸿蒙跨端实践-长列表解决方案和性能优化

这是我参加创作者计划的第一篇文章。 前言 长列表是前端和客户端应用中最常见的业务场景&#xff0c;比如商品瀑布流等&#xff0c;有成千上万条数据&#xff0c;因此长列表的渲染性能在iOS&#xff0c;Android&#xff0c;Harmony&#xff0c;Web等各大平台都非常重要。Harmon…

uni-app进度条

<template><view><canvas canvas-id"ring" id"ring" style"width: 200px; height: 180px;"><!-- <p>抱歉&#xff0c;您的浏览器不支持canvas</p> --></canvas></view> </template><…

Frp经常连接不上?查看Frp常见问题排查

很多使用Frp的网友反馈使用Frp经常出现无法使用或者不稳定的情况&#xff0c;Frp编译和部署比较复杂&#xff0c;多端口映射时或者连接数多的情况下会出现不稳定的现象&#xff0c;不适合小白使用&#xff0c;而且仅是上一代的内网穿透技术&#xff0c;生产环境使用建议选择稳定…

Linux创建用户配置虚拟环境

文章目录 前言一、创建新用户二、下载安装Anaconada总结 前言 本篇文章用于记录拿到一个新的Linux服务器开始创建一个新的用户&#xff0c;并配置深度学习所需要的环境。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、创建新用户 创建用户&…

苏轼为何要写石钟山记?时间节点是关键

《石钟山记》不仅是苏轼的旅行笔记&#xff0c;亦是其人生哲学与思想的深邃自省。文中不仅详述了他对石钟山的实地勘察&#xff0c;亦体现了其对历史、自然及人生之独到见解。黄州生涯及其对政治与文化的洞悉&#xff0c;为这篇作品注入了深厚底蕴。 苏轼的黄州岁月 黄州期间…

使用现有的科技或许无法实现对人类智能的模拟

现有科技在实现真正的人类智能方面面临许多挑战。科技的局限性涉及许多领域&#xff0c;在计算能力方面&#xff0c;尽管处理速度不断提升&#xff0c;但要模拟人脑的复杂性仍然困难重重&#xff1b;当前的人工智能依赖于大量数据进行训练&#xff0c;缺乏灵活性和适应性&#…

状态模式原理剖析

《状态模式原理剖析》 状态模式&#xff08;State Pattern&#xff09; 是一种行为设计模式&#xff0c;它允许对象在其内部状态改变时改变其行为。换句话说&#xff0c;当对象状态发生变化时&#xff0c;它的行为也会随之变化。 通过状态模式&#xff0c;可以消除通过 if-else…

Sam Altman最新博文:智能时代将带来无限的智能和丰富的能源

9 月 23 日&#xff0c;Sam Altman 发布了一篇名为《The Intelligence Age》 的博客文章。Altman 强调&#xff0c;未来的科技进步将让我们做出在祖辈看来近乎“魔法”的成就&#xff0c;AI 的加速创新将成为推动这些 变革的核心力量。 Altman 解释说&#xff0c;历史上人类之所…

MySQL数据库脚本转化成sqlite数据库脚本的修改点

转换数据类型 将MySQL的数据类型转换为SQLite对应的数据类型。例如&#xff0c;将 INT或 INTEGER 转换为 INTEGER&#xff0c;将 VARCHAR、TEXT 或 CHAR 转换为 TEXT&#xff0c;将 DATETIME 或 TIMESTAMP 转换为 TEXT 或 DATETIME&#xff08;SQLite没有专门的日期时间类型&am…

IM项目中即时消息管理的技术实现及优劣分析

基于TCP协议的实现 技术原理 TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。在IM项目中&#xff0c;使用TCP协议进行即时消息管理时&#xff0c;客户端和服务器之间首先建立连接。当发送消息时&#xff0c…

240924-Windows映射网络驱动器的方法

在Windows上加载网络盘&#xff08;映射网络驱动器&#xff09;可以通过以下步骤完成&#xff1a; 方法一&#xff1a;通过文件资源管理器 打开文件资源管理器&#xff1a; 可以按 Win E 打开&#xff0c;或者直接点击任务栏上的文件资源管理器图标。 点击“此电脑”&#x…

Java 安全认证和 Hadoop UGI 原理解析

Java 安全认证和 UGI 原理解析 一般来说&#xff0c;Java 安全认证主要通过自定义 Subject、LoginContext、LoginModule、Configuration 在 Java 中进行安全认证。 Subject 可以单独创建并通过 Subject#doAs 方法单独进行登录&#xff0c;但也可以传入 LoginContext 中&#x…

在Java中,关于final、static关键字与方法的重写和继承【易错点】

在Java中&#xff0c;关于final、static关键字与方法的重写和继承【易错点】 1.final方法不能被重写2.static方法不是重写&#xff0c;而是遮蔽3.final与static的组合4.final与继承5.static与继承 1.final方法不能被重写 如果父类中的方法被声明为final&#xff0c;那么这个方法…

Codeforces Beta Round 2 B. The least round way(线性DP/数论)

题目&#xff1a; There is a square matrix n  n, consisting of non-negative integer numbers. You should find such a way on it that starts in the upper left cell of the matrix;each following cell is to the right or down from the current cell;the way ends…

Facebook对现代社交互动的影响

自2004年成立以来&#xff0c;Facebook已经成为全球最大的社交媒体平台之一&#xff0c;改变了人们的交流方式和社交互动模式。作为一个数字平台&#xff0c;Facebook不仅为用户提供了分享生活点滴的空间&#xff0c;也深刻影响了现代社交互动的各个方面。本文将探讨Facebook如…