云南大学软件学院
School of Software, Yunnan University
成绩
学
期:
2011 秋季学期
课程名称:
密码技术
任课教师:
学生姓名:
学
号:
实验项目:
联系电话:
电子邮件:
实验一
完成提交时间:
年 月 日
密码技术实验报告
实验项目:实验一,第 1 题 实现维吉尼亚密码的加密和解密
实验要求
(内容)
实现维吉尼亚密码,用键盘接收明文和密钥,屏幕打印密文和解密后的明文。
要求大小写敏感,明文小写则密文大写,明文大写则密文小写输出,注意输入的
健壮性控制,明文字符超出字符集后保留原文。
操作系统:win7
实验环境
编译环境:Microsoft Visual Studio 2010
本次实验达到了题目的要求:
实现维吉尼亚密码,用键盘接收明文和密钥,屏幕打印密文和解密后的明文;
明文小写则密文大写,明文大写则密文小写输出,明文字符超出字符集后保
实现功能
留原文。
主函数的操作也充分体现了程序的可操作性和健壮性,能够让用户自己选择
相应的操作,比如加密、解密以及对程序的一些基本情况说明。
但是对密钥的输入有较多的约束。首先,输入的密钥必须是小写字母,不能
是其它的字符,否则加解密的过程会出现错误。
数据结构
本次实验过程中用到的主要数据结构为数组,在实验中我定义了多个字符数
组,如 char plaintext[100]声明字符数组存储明文,char ciphertext[100]声明字符数
组存储密文,char key[100]声明字符数组存储密钥,并且通过对数组下标的操作
完成对明文、密钥和密文的处理,根据用户输入的明密文以及密钥得到相对应的
密明文。这个程序的实现并不是很复杂,因此也没有采用更多的数据结构。
程序模块结构图:
开 始
start
选择操作
选择加密
调用加密函数
选择说明或退出
调用说明函数
选择解密
调用解密函数
用户输入明文和密钥(或者是密文和密钥),并用数组
plaintext[100]接收存储明文(或用数组 ciphertext[100]接收存
储密文),然后用数组 key[100]接收存储密钥。
程序流程
判断输入密
钥的合法性
是
重新输入密钥
加密的核心过程:明文小(大)写字母加上相应的密钥字母得到大(小)写
的密文字母,超出字符集的符号保留原文。
解密的核心过程:密文小(大)写字母减去相应的密钥字母得到大(小)写
的明文字母,超出字符集的符号保留原文。
输出明(密)文及所对应的密(明)文
函数的调用关系:
主函数 main()
加密函数 Encrypt()
解密函数 Decrypt()
说明函数 Explain()
主要函数的接口、调用与被调用函数、所实现的功能和实现的主要思路:
int main(char ch) :
Function:
为用户提供基本操作,调用加密解密函数。
Calls:
调用了加密函数 Encrypt(),解密函数 Decrypt()和程序说明函数 Explain()。
Called By:
未被其它函数调用。
Input(type)
字符型(char)。
Output(type): 无,只是输出“”中的字符串。
Return(type): 整型
Others:
Bug:
无
测试尚未发现
代 码 与 代
码分析
void Encrypt(char plaintext[],char key[])
Function: 实现的功能是:接收明文和密钥的输入,并使用维吉尼亚密码进行加密,然
后输出密文。
实现的主要思路:首先用 gets()函数接收明文和密钥的输入,然后对密钥进
行检查,若出现除小写字母外的其它字符则返回重新输入;加密的核心算法是(以
明文小写字母为例):ciphertext[i]=((plaintext[i]-'a')+(key[i%k_len]-'a'))%26+'A',利
用对数组的下标操作一次取出明文字母和密钥字母,然后明文字母和密钥字母都减
去'a',得到明文字母和密钥字母在字母表中的序号,二者相加再模 26 后即可得到
密文字母在字母表中的序号,最后再加上'A'即可得到对应的密文字母。
key[i%k_len]包含了对密钥的处理,若明文字母长度比密钥长度长时,用公式
i%k_len 可以使 plaintext[i]与密钥字母(重复多次)一一对应。
Calls:
未调用其它函数。
Called By:
被主函数 main()调用。
Input(type)
字符型(char)。
Output(type): 字符型(char)。
Return(type): 无返回值的类型。
Others:
无
Bug:
测试中尚未发现
void Decrypt(char ciphertext[],char key[])
Function: 实现的功能是:接收密文和密钥的输入,并使用维吉尼亚密码进行解密,然
后输出明文。
实现的主要思路:首先用 gets()函数接收密文和密钥的输入,然后对密钥进
行检查,若出现除小写字母外的其它字符则返回重新输入;解密的核心算法是(以
明文小写字母为例):plaintext[i]=((ciphertext[i]-'A')-(key[i%k_len]-'a'))%26+'a',利
用对数组的下标操作一次取出密文字母和密钥字母,然后密文字母和密钥字母分别
减去'A'和'a',得到密文字母和密钥字母在字母表中的序号,二者相减再模 26 后即
可得到明文字母在字母表中的序号,最后再加上'A'或'a'即可得到对应的明文字母。
key[i%k_len]包含了对密钥的处理,若密文字母长度比密钥长度长时,用公式
i%k_len 可以使 plaintext[i]与密钥字母(重复多次)一一对应。
Calls:
未调用其它函数。
Called By:
被主函数 main()调用。
Input(type)
字符型(char)。
Output(type): 字符型(char)。
Return(type): 无返回值的类型。
Others:
Bug:
无
测试中尚未发现
实验输入:先选择加密,然后输入明文:my name is yqg! 密钥:yqg
选择解密,然后输入密文:ko lqsc oq eow! 密钥:yqg
实 验 输 入
( 可 加 截
图):
选择加密,然后输入明文:my name is yqg! 密钥:yqg 加密后输出的结果
是:KO LQSC OQ EOW!
结 果 输 出
( 可 加 截
图):
选择解密,然后输入密文:ko lqsc oq eow! 密钥:yqg 解密后输出的结果
是:MY NAME IS YQG!
实验项目:实验一,第 2 题 实现单表替换密码的加密和解密
实验要求
(内容)
实现单表替换密码,用键盘接收明文和密钥,屏幕打印替换表和密文。
要求:大小写敏感,明文小写则密文大写,明文大写则密文小写输出,注意
输入的健壮性控制,明文字符超出字符集后保留原文
操作系统:win7
实验环境
编译环境:Microsoft Visual Studio 2010
本次实验达到了题目的要求:
实现单表替换密码,用键盘接收明文和密钥,屏幕打印密文和解密后的明文;
明文小写则密文大写,明文大写则密文小写输出,明文字符超出字符集后保
实现功能
留原文。
主函数的操作也充分体现了程序的可操作性和健壮性,能够让用户自己选择
相应的操作,比如加密、解密以及对程序的一些基本情况说明。
但是对密钥的输入有较多的约束。首先,输入的密钥必须是小写字母,不能
是其它的字符,否则加解密的过程会出现错误。
数据结构
本次实验过程中用到的主要数据结构为数组,在实验中我定义了多个字符数
组,如 char plaintext[100]声明字符数组存储明文,char ciphertext[100]声明字符数
组存储密文,char key[100]声明字符数组存储密钥,char table[27]声明字符数组存
储字母表,并且通过对数组下标的操作完成对明文、密钥和密文的处理,根据用
户输入的明密文以及密钥得到相对应的密明文。这个程序的实现并不是很复杂,
因此也没有采用更多的数据结构。
程序模块结构图:
开 始
start
选择操作
选择加密
调用加密函数
选择说明或退出
调用说明函数
选择解密
调用解密函数
用户输入明文和密钥(或者是密文和密钥),并用数组 plaintext[100]
接收存储明文(或用数组 ciphertext[100]接收存储密文),然后用
数组 key[100]接收存储密钥。若明密文是大写则需先转换为小写。
程序流程
判断输入密
钥的合法性
是
否
重新输入密钥
单表替换加解密的核心过程:构建替换表。首先,将字母表接在输入的
密钥字符串之后构成最初的替换表,然后对替换表进行循环操作,若发现有
重复的字母,直接将该后面重复的字母删除,最终构成有 26 个无序字母组
成的替换表。
加密的核心过程:首先字母表与替换表一一对应,在字母表中找到明文字母
然后转换成与该字母对应的替换表中的字母,超出字符集的符号保留原文。
解密的核心过程:首先字母表与替换表一一对应,在替换表中找到密文字母
然后转换成与该字母对应的字母表中的字母,超出字符集的符号保留原文。
若输入的明(密)文是小写,则需先将密
(明)文转换成大写,然后输出