news 2026/2/16 2:09:43

C语言实现维吉尼亚密码加解密算法(附带源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言实现维吉尼亚密码加解密算法(附带源码)

一、项目背景详细介绍

1. 密码学的历史脉络

在现代密码学兴起之前,人类自古就利用各种方法隐藏信息以避免在传递过程中被对手窃取。在古典密码体系中,最具代表性的包括凯撒密码(Caesar Cipher)、仿射密码(Affine Cipher)、希尔密码(Hill Cipher)等,而维吉尼亚密码(Vigenère Cipher)是其中影响最深远、使用最长期的一种加密方式。

维吉尼亚密码由法国外交官Blaise de Vigenère在 16 世纪末提出,它被视为“多表代换密码”的典型代表。由于其使用多个不同的替换字母表进行加密,因此比凯撒密码等单表代换方式更难破解,即使面对现代分析工具,在不知道密钥的前提下也有一定破解成本。

2. 多表替换思想

维吉尼亚密码的关键思想是 ——使用一个密钥(单词)决定每个字符的偏移量
例如:
若密钥为KEY,即偏移量依次为:

  • K → 10

  • E → 4

  • Y → 24

因此明文第 1 个字符用 10 偏移,第 2 个用 4,第 3 个用 24,第 4 个再循环使用 K 的偏移 10,如此往复。

这种将密钥重复作用于明文的方式有效增强了安全性,使得通过频率分析来破解变得困难。

3. 现代视角下的维吉尼亚密码

虽然现代密码算法已完全不同类别,如对称加密 AES、非对称加密 RSA、椭圆曲线等,但古典密码仍具有以下价值:

  • 入门密码学的重要材料

  • 有助于理解模运算、字符编码、代换密码原理

  • 适合教学与嵌入式场景、资源极低环境使用

  • 仍用于某些娱乐、安全演示、CTF(夺旗赛)题目

因此实现维吉尼亚密码具有非常强的教学意义。


二、项目需求详细介绍

本项目需实现一个完整的C 语言维吉尼亚密码加解密系统。需求如下:

1. 实现功能

  • 加密加密(Encrypt)

  • 解密解密(Decrypt)

  • 大小写保持一致

  • 非字母字符保持不变

  • 密钥循环使用

2. 支持的输入类型

  • 英文字母文本(可包含大小写)

  • 标点、数字不加密

  • 任意长度密钥

3. 程序特性要求

  • 单文件可编译

  • 代码包含充分注释

  • 加密与解密借助统一逻辑

  • 模 26 运算处理字符偏移

  • 提供命令行与交互模式

4. 错误处理

  • 密钥必须为字母

  • 字符串为空需给出提示

  • 密钥长度不可为 0

5. 文件结构要求

根据你的记忆规则,本项目所有代码放在一个代码块内,不同文件用注释分隔。


三、相关技术详细介绍

1. 字符与整数之间的关系(ASCII)

维吉尼亚密码依赖字符偏移,因此需要掌握:

  • 'A' ~ 'Z'连续

  • 'a' ~ 'z'连续

  • 大小写各自独立运算

例如:

int offset = ch - 'A'; // (0 ~ 25) int result = (offset + keyOffset) % 26; char encrypted = 'A' + result;

2. 模运算与正代表

在计算解密时会出现负数,需要保证结果回到 0..25 之间。

x = (x % 26 + 26) % 26;

3. 循环密钥

如果密钥为“KEY”,明文长度为 n,则:

keyIndex = i % keyLength;

4. 加密公式

对于明文字符 P,密钥字符 K:

C = (P + K) mod 26

5. 解密公式

P = (C - K + 26) mod 26

6. 大小写保持

加密不改变原始字符大小写,因此:

  • 若字符为大写 → 使用大写字母表

  • 若字符为小写 → 使用小写字母表

7. 非字母过滤

对数字、空格、标点不处理。


四、实现思路详细介绍

1. 总体结构设计

程序将包含以下模块:

  • validateKey():检查密钥是否合法

  • charToOffset():字母转 0..25

  • encryptChar():对单字符加密

  • decryptChar():对单字符解密

  • encryptString():对整串文本加密

  • decryptString():对整串文本解密

  • main():入口(命令行 + 交互模式)

2. 加密流程

  1. 遍历文本

  2. 若是字母:

    • 取密钥当前位置字符

    • 计算偏移

    • 执行加密运算

    • 更新密钥索引

  3. 若非字母:

    • 直接复制,密钥不前进

3. 解密流程

解密与加密基本相同,只是公式不同:

P = (C - K + 26) mod 26

4. 关键性技术点

  • 大小写分别处理

  • 可变长度密钥,通过取模循环

  • 负数处理

  • 对字符串操作安全性保证


五、完整实现代码

/************************************* * 文件:vigenere.c * 功能:实现维吉尼亚密码加解密算法 *************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> /*------------------------------------ 工具函数:返回字符对应的 0~25 偏移 -------------------------------------*/ int charToOffset(char c) { if (isupper((unsigned char)c)) return c - 'A'; else return c - 'a'; } /*------------------------------------ 工具函数:判断密钥是否合法(仅字母) -------------------------------------*/ int validateKey(const char *key) { if (!key || strlen(key) == 0) return 0; for (size_t i = 0; i < strlen(key); i++) { if (!isalpha((unsigned char)key[i])) return 0; } return 1; } /*------------------------------------ 单字符加密 -------------------------------------*/ char encryptChar(char p, char k) { int pOff = charToOffset(p); int kOff = charToOffset(k); int c = (pOff + kOff) % 26; if (isupper((unsigned char)p)) return 'A' + c; else return 'a' + c; } /*------------------------------------ 单字符解密 -------------------------------------*/ char decryptChar(char c, char k) { int cOff = charToOffset(c); int kOff = charToOffset(k); int p = (cOff - kOff + 26) % 26; if (isupper((unsigned char)c)) return 'A' + p; else return 'a' + p; } /*------------------------------------ 整串加密 -------------------------------------*/ char *encryptString(const char *text, const char *key) { size_t n = strlen(text); size_t keyLen = strlen(key); char *res = (char *)malloc(n + 1); size_t keyIndex = 0; for (size_t i = 0; i < n; i++) { char ch = text[i]; if (isalpha((unsigned char)ch)) { char k = key[keyIndex % keyLen]; res[i] = encryptChar(ch, k); keyIndex++; } else { res[i] = ch; } } res[n] = '\0'; return res; } /*------------------------------------ 整串解密 -------------------------------------*/ char *decryptString(const char *text, const char *key) { size_t n = strlen(text); size_t keyLen = strlen(key); char *res = (char *)malloc(n + 1); size_t keyIndex = 0; for (size_t i = 0; i < n; i++) { char ch = text[i]; if (isalpha((unsigned char)ch)) { char k = key[keyIndex % keyLen]; res[i] = decryptChar(ch, k); keyIndex++; } else { res[i] = ch; } } res[n] = '\0'; return res; } /*------------------------------------ 交互模式 -------------------------------------*/ void interactiveMode() { char mode[8]; char key[256]; char text[2048]; printf("请选择模式(enc = 加密,dec = 解密):"); scanf("%7s", mode); printf("请输入密钥(仅字母):"); scanf("%255s", key); if (!validateKey(key)) { printf("密钥非法,必须全为字母。\n"); return; } getchar(); // 清除换行符 printf("请输入文本:\n"); fgets(text, sizeof(text), stdin); size_t len = strlen(text); if (len > 0 && text[len - 1] == '\n') text[len - 1] = '\0'; if (strcmp(mode, "enc") == 0) { char *out = encryptString(text, key); printf("加密结果:\n%s\n", out); free(out); } else if (strcmp(mode, "dec") == 0) { char *out = decryptString(text, key); printf("解密结果:\n%s\n", out); free(out); } else { printf("未知操作。\n"); } } /*------------------------------------ 主函数:命令行 + 交互模式 -------------------------------------*/ int main(int argc, char *argv[]) { if (argc == 1) { interactiveMode(); return 0; } if (argc != 4) { printf("用法:\n"); printf(" %s enc 密钥 文本\n", argv[0]); printf(" %s dec 密钥 文本\n", argv[0]); return 1; } char *mode = argv[1]; char *key = argv[2]; char *text = argv[3]; if (!validateKey(key)) { printf("密钥非法,必须全为字母。\n"); return 1; } if (strcmp(mode, "enc") == 0) { char *out = encryptString(text, key); printf("%s\n", out); free(out); } else if (strcmp(mode, "dec") == 0) { char *out = decryptString(text, key); printf("%s\n", out); free(out); } else { printf("未知操作:%s\n", mode); return 1; } return 0; }

六、代码详细解读

下面对每个函数进行功能说明:

1.charToOffset()

将字母映射到 0 ~ 25,便于执行模运算。

2.validateKey()

确保密钥由字母构成,防止出现数字或特殊字符。

3.encryptChar()

对单字符执行加密公式:

C = (P + K) mod 26

根据原字符是否为大写决定输出范围。

4.decryptChar()

执行解密公式:

P = (C - K + 26) mod 26

保证结果不为负数。

5.encryptString()

按顺序遍历明文,遇到字母执行加密,同时推进密钥索引。

6.decryptString()

同上,只是执行解密。

7.interactiveMode()

用于无参数运行时的交互输入模式,便于测试和演示。

8.main()

主入口,支持两种运行方式:

  • 无参数 → 进入交互

  • 命令行参数格式 → 直接加解密


七、项目详细总结

本项目实现了一个完整、稳健、可复用的维吉尼亚密码加解密系统,涵盖以下要点:

  • 使用 C 语言实现古典密码

  • 模 26 运算的核心逻辑

  • 大小写保持与非字母保留策略

  • 循环密钥机制的实现

  • 安全的字符串处理

  • 命令行与交互模式双支持

通过本项目,读者可以学习到:

  • 如何使用 ASCII 与模运算实现代换密码

  • 多表代换密码的原理

  • 如何设计一个安全且清晰的 C 程序结构


八、项目常见问题及解答

问题 1:为什么密钥需要循环?

因为明文通常比密钥长,维吉尼亚密码的规则就是密钥重复使用。

问题 2:非字母为什么不加密?

这是维吉尼亚密码的基本规则,且保持字符形态一致更便于阅读。

问题 3:大小写是否独立处理?

是的。
因为大小写 ASCII 区间不同,必须独立计算。

问题 4:如果想支持 UTF-8 中文怎么办?

维吉尼亚密码只能用于 26 字母表,中文需采用替代方案,例如对子节数据加密或使用现代密码学算法。

问题 5:密钥能包含大写吗?

可以,全为字母即可,加密时会自动处理。


九、扩展方向与性能优化

1. 扩展到 95 字符 ASCII 可打印字符表

将字符映射范围从 26 扩展到 95,更类似现代替换密码。

2. 加入文件加密功能

支持:

vigenere enc key input.txt output.txt

3. 将其编写为独立库

适合在更复杂系统中调用。

4. 引入自动检测模式(破解维吉尼亚密码)

如添加Kasiski Examination(卡西斯基分析)

5. 优化速度

大量使用循环时可批量处理、SIMD 加速等。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/15 5:15:16

C语言实现仿射变换加解密算法(附带源码)

一、项目背景详细介绍在现代密码学研究中&#xff0c;虽然我们主要使用对称加密算法&#xff08;如 AES&#xff09;、非对称加密算法&#xff08;如 RSA、ECC&#xff09;、哈希函数、认证协议等&#xff0c;但在密码学历史发展过程中&#xff0c;早期的加密方式&#xff08;称…

作者头像 李华
网站建设 2026/2/11 3:47:42

C语言实现文件分割(附带源码)

一、项目背景详细介绍在现代计算机系统中&#xff0c;文件操作是非常常见的任务。特别是在处理大文件时&#xff0c;我们经常会遇到各种实际需求&#xff0c;例如&#xff1a;将超大日志文件按大小拆分以便上传将大型二进制文件拆分成多个部分以便传输实现断点续传或分片上传功…

作者头像 李华
网站建设 2026/2/14 18:28:04

C语言实现辗转相除法(附带源码)

一、项目背景详细介绍在数学与计算机科学领域中&#xff0c;辗转相除法&#xff08;Euclidean Algorithm&#xff09; 是一种极其经典且高效的算法&#xff0c;它可以用于求解任意两个整数的最大公约数&#xff08;Greatest Common Divisor, GCD&#xff09;。最大公约数的计算…

作者头像 李华
网站建设 2026/2/7 14:37:35

C语言实现学生管理系统(附带源码)

一、项目背景详细介绍学生管理系统&#xff08;Student Management System&#xff09;是计算机基础课程、数据结构与软件工程入门课程中常见的综合实训题目。该系统通过对学生信息的增删改查&#xff08;CRUD&#xff09;实现对实体数据的管理&#xff0c;是练习结构体、文件 …

作者头像 李华
网站建设 2026/2/6 7:39:23

多站点跨境电商平台数据 API 接口接入与说明

跨境电商多站点数据采集的核心是统一接口适配不同站点规则&#xff0c;同时兼顾合规性、数据一致性和稳定性。以下是主流跨境平台&#xff08;亚马逊、速卖通、Shopee、Lazada&#xff09;多站点 API 的接入流程、核心能力及实操说明&#xff0c;附带 Python 对接示例。一、多站…

作者头像 李华
网站建设 2026/2/12 8:39:01

网络国际出口怎么选?企业如何避免踩坑?

说起网络国际出口&#xff0c;很多企业的IT部门或许会感到头疼。这不仅是因为它涉及的技术相对复杂&#xff0c;还因为市场上产品众多&#xff0c;让人眼花缭乱。那么&#xff0c;究竟该如何挑选适合自己的网络国际出口方案呢?让我们一起看看。首先得明白&#xff0c;网络国际…

作者头像 李华