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

如何使用C语言实现Vigenre密码加解密

如何使用C语言实现Vigenère密码加解密

在洛谷看到这题,觉得有意思,遂写。

参考文章:C语言实现Vigenere加解密算法(附带源码)

1. Vigenère密码简介与原理

Vigenère密码是一种多表密码,使用一系列凯撒密码(Caesar cipher)来实现加密。在Vigenère密码中,明文中的每个字符都被替换为密文中的对应字符,而密钥用于确定使用哪个凯撒密码表。具体来说,明文中的每个字符都会根据密钥中的字符进行位移,从而生成密文。如图:img
加密例子:明文:HELLO,密钥:KEY,加密后:RIJVS

对照表中,先将密钥填充至与明文长度相同:KEYKE。然后在对照表中找到明文字符对应的密文字符,如第一个字符在对照表中的K行找到H列,对应的字符是R,于是第一个字符就被加密成R。以此类推,直到明文全部加密完成。

实际操作中,其实就是一系列的不同的凯撒密码加密,而密钥决定了使用哪个凯撒密码表,这里不赘述。我们把字母转换成数字(A = 0,B = 1,……),写成公式可以表达成:

加密:C = (P + K)% 26

其中C为密文字符,P为明文字符,K为密钥字符。同样可以得到解密公式:

解密:P = (C - K + 26)% 26

2.具体实现

这里仅给出函数实现,以及省略了引入string.h和ctype.h头文件。

我们可以考虑先忽略字母的大小写,解密后再对照原文判断是否转换大小写。先实现字母转数字、数字转字母的函数:

int Char_to_Number(char c)
{return c - 'A';
}char Number_to_Char(int num, char origin)
{char c = 'A' + num;//* 对照原文if (islower(origin)){return tolower(c);}return c;
}

解码:

char *Decode(char *key, char *C, char *M)
{for (int i = 0, j = 0; i < strlen(C); i++){if (isalpha(C[i])){int keyNum = Char_to_Number(key[j % strlen(key)]); // 填充密钥int CNum = Char_to_Number(C[i]);int MNum = (CNum - keyNum + 26) % 26;M[i] = Number_to_Char(MNum, C[i]);// 不能在循环体里面写j++😡,否则遇到非字母字符j也会增加j++; }else{M[i] = C[i];}}return M;
}

加密:

char *Encode(char *key, char *M, char *C)
{for (int i = 0, j = 0; i < strlen(M); i++){if (isalpha(M[i])){int keyNum = Char_to_Number(key[j % strlen(key)]);int MNum = Char_to_Number(M[i]);int CNum = (MNum + keyNum) % 26;C[i] = Number_to_Char(CNum, M[i]);j++;}else{C[i] = M[i];}}
}

完整测试用例代码:

#include <stdio.h>
#include <string.h>
#include <ctype.h>int Char_to_Number(char c);
char Number_to_Char(int num, char origin);
char *Decode(char *key, char *C, char *M);
char *Encode(char *key, char *M, char *C);int main()
{char key[101];char C[1001];char M[1001];fgets(key, sizeof(key), stdin);fgets(C, sizeof(C), stdin);key[strcspn(key, "\n")] = '\0';C[strcspn(C, "\n")] = '\0';Decode(key, C, M);printf("%s\n", M);// Encode(key, M, C);// printf("%s\n", C);return 0;
}int Char_to_Number(char c)
{return toupper(c) - 'A';
}char Number_to_Char(int num, char origin)
{char c = 'A' + num;//* 对照原文if (islower(origin)){return tolower(c);}return c;
}char *Decode(char *key, char *C, char *M)
{for (int i = 0, j = 0; i < strlen(C); i++){if (isalpha(C[i])){int keyNum = Char_to_Number(key[j % strlen(key)]); // 填充密钥int CNum = Char_to_Number(C[i]);int MNum = (CNum - keyNum + 26) % 26;M[i] = Number_to_Char(MNum, C[i]);j++; // 不能在循环体里面写j++😡,否则遇到非字母字符j也会增加}else{M[i] = C[i];}}return M;
}char *Encode(char *key, char *M, char *C)
{for (int i = 0, j = 0; i < strlen(M); i++){if (isalpha(M[i])){int keyNum = Char_to_Number(key[j % strlen(key)]);int MNum = Char_to_Number(M[i]);int CNum = (MNum + keyNum) % 26;C[i] = Number_to_Char(CNum, M[i]);j++;}else{C[i] = M[i];}}
}

3. 总结

知道了加解密公式,实现起来就很简单,以及注意需要对照原文判断转换字母的大小写。

http://www.gsyq.cn/news/10191.html

相关文章:

  • 嵌入式硬件工程师每日提问 - 指南
  • JavaScript获取NHK的附件文件
  • 承兑 背书 贴现区别
  • 完整教程:网络安全期末大论文
  • 基于解析法的四轴SCARA机器人正逆运动学代码
  • redis-list类型基本命令
  • 程序员的未来:从技术岗位到全栈思维的进化之路 - 实践
  • 国产化Excel处理组件Spire.XLS教程:Java在 Excel 表格中轻松添加下标
  • tips图解复杂数组、指针声明
  • 通过perl或awk实现剪切功能
  • 详细介绍:麒麟v10服务器安装libvirt
  • 9.23 资料分析 7/10
  • VMware ESXi 磁盘置备类型详解
  • HWiNFO 硬件信息检测工具下载与安装教程
  • 西电PCB设计指南1~2章学习笔记
  • 逆向分析之switch语句
  • 搭建Python的运行开发环境
  • 【HBase 原理操作 01】
  • 打破数据壁垒,DMS Data Agent 开启智能分析之旅
  • 光隔离探头技术解析:高电压测量的安全革命​​
  • 从缺陷管理到质量协作:现代Bug工具的范式升级
  • 螺旋矩阵-leetcode
  • 完整教程:2020年_408统考_数据结构41题
  • Gitee本土化创新实践:中国企业研发效能提升的新引擎
  • 详细介绍:nvm使用和node使用
  • Markdown的基本语法
  • containerd离线安装
  • Python3 urllib 详解
  • WCF-双工通讯
  • 跨网文件安全交换系统:打破数据壁垒的高效之选!