标准文案
学生学号***实验课成绩
学生实验报告书
实验课程名称
开课学院
指导教师姓名
学生姓名
学生专业班级
MIS系统软件
管理学院
***
**
2011
大全
--2012学年第二学期
标准文案
实验项目名称加密解密算法
实验者
同组者
**专业班级信管0901班
无
实验成绩
组别
实验日期2012年03月07日
大全
标准文案
第一部分:实验预习报告
1、实验目的、意义
通过简单的加密解密算法的实现理解系统中加密解密的基本思想,熟练掌握使用C语言基
本语句。
2、实验基本原理与方法
①单字母替换加密方法——恺撒密码
加密方法是把英文字母按字母表的顺序编号作为明文,将密钥定为m,加密算法为将明文
加上密钥m,得到密码表,通过相反的过程由密文得到明文。
②单字母替换加密方法——单表置换密码
由密钥Key构造字符置换表,完成加密和解密过程。
③多字母替换加密方法——维吉利亚密码
假设明文m=m1m2m3…mn;密钥k=k1k2k3…kn,对应密文c=c1c2c3…cn,密文
为:ci=(mi+ki)mod26,26个字母的序号依次为0~25,ci,mi,,ki是分别是密文明文
密钥中第i个字母的序号。
④转换加密方法
通过将明文每m个字符一组按顺序分为若干个字符串,再按照先列后行形成密文,并分
析给出解密的方法。
或者通过给出一个密钥字符串,将明文按密钥字符串长度按顺序分为若干组字符串,再
按照密钥字符串各个字符的顺序形成密文,并分析给出解密的方法。
3、主要仪器设备及耗材
实验室提供计算机和上网条件,C语言上机环境。
4、实验方案与技术路线(综合性、设计性实验)
大全
标准文案
第二部分:实验过程记录
实验原始记录(包括实验数据记录,实验现象记录,实验过程发现的问题等)
1.单表置换:
先选定一个单词,例如BEIJIGTSIGHUA,然后将它排列在密码对照表(两行26列第一行
存a到z的字母,第二行存对照的密码)下方,重复出现的字母以第一次现时对应的明文字母
为准;后面以该单词中未出现的字母按顺序排列备齐,生成一个密码,然后可以用此密码本进
行加密或解密。
加密过程:首先输入加密明文如important,然后输入密钥如BEIJIGTSIGHUA。再然后建
立临时密码表如下:(上一行是字母,下一行是密码)
之后,将important对照第一行的相应密匙如i对应H,依次输出。结果应为HDLKOQBFQ;
解密过程:首先输入密文如HDLKOQBFQ,然后输入密匙BEIJIGTSIGHUA。同理加密过程,
可以对照密码表依次到密文中对应的原文。结果应为important。
2.凯撒密码:
把英文字母按字母表的顺序编号作为明文,将密钥定为m,加密算法为将明文加上密钥m,
得到密码表,通过相反的过程由密文得到明文。
加密过程:首先输入明文为Thisisasecret,然后输入密钥9,之后同样会形成两行对
应的同1方法一样的密码表:
ABCDEFGHIJKLMOPQRSTUVWXYZ
XYZABCDEFGHIJKLMOPQRSTUVW
之后,将自动输出加密后的密文,结果为:cqrb!rb!j!bnlanc;
解密过程:输入需要解密的密文如:cqrb!rb!j!bnlanc,然后输入密钥9(为简便起见,
同加密过程使用同样的密钥),则得到加密过程中的同样密码表,然后依次对应输出原文,结
果为Thisisasecret。
3.轮转法:
大全
标准文案
通过将明文每m个字符一组按顺序分为若干个字符串,再按照先列后行形成密文,并分析
给出解密的方法。
加密过程:首先输入明文itcanallowstudentstogetcloseupviews,然后输入密匙
5,之后输入的明文会按照每行3个字符的形式进行排列,如此例中形成如下的排列:
之后,输出加密后的密文则使用先列后行的方法,此例结果为:
iasngovtlttesiclusteeaodtcuwnweolps;
解密过程:首先输入密文icteccnrbouicumsanb,然后输入密匙5,之后同样会将输入
的密文按照每行3个字符的形式排列,形成如下排列:
icbca
ccoun
tnumb
eris
之后,输出解密后的明文使用先列后行的方法,此例结果为icbcaccountnumberis。
4.维吉利亚密码:
假设明文m=m1m2m3…mn;密钥k=k1k2k3…kn,对应密文c=c1c2c3…cn,
密文为:ci=(mi+ki)mod26,26个字母的序号依次为0~25,ci,mi,,ki是分别是密文
明文密钥中第i个字母的序号。(如下图)
加密过程:首先输入明文如information,然后输入密匙如star,第一个字符的密文可
以求得c1=(w+i)mod26=4,,此时对应编号4的字母为E,则明文W对应的密文为E,依次类推,
可以将所有明文加密得到密文:AGFFJFAKAH;
大全
标准文案
解密过程:首先输入密文esioqgm,然后输入与密文字符数相等的密匙如iloveyu,将加
密过程的原理反过来运用,如第一个密文字符为E,则对应的编号为4,然后求的明文为W,依
次类推,求得明文为:whutmis。
大全
标准文案
第三部分结果与讨论(可加页)
实验结果分析(包括数据处理、实验现象分析、影响因素讨论、综合分析和结论等)
程序设计类实验:包括原程序、输入数据、运行结果、实验过程发现的问题及解决方法等;
分析与设计、软件工程类实验:编制分析与设计报告,要求用标准的绘图工具绘制文档中
的图表。系统实施部分要求记录核心处理的方法、技巧或程序段;
其它实验:记录实验输入数据、处理模型、输出数据及结果分析
运行结果分析:
在vc++6.0的编译环境下,点击运行后出现加密算法选择的界面:
(1)凯撒密码
选择1后回车,阅读完介绍性文字后,再接着选择1进行对输入字符串进行加密(例如
输入字符串"******'sbirthdayis",接着输入密钥7):
大全
标准文案
得到密文:govbephv(z!ipyaokhf!pz!
此时我为了对一段字符串进行凯撒解密"govbephv(z!ipyaokhf!pz!",同时输入密钥7,同
样会得到加密前的明文:
(2)单表置换密码
按照提示,回车后又进入加密算法选择主界面,此时选择2.单表置换密码,加密下面
一句话todayisapril1,2012,namelyAprilfool'sday:
大全
标准文案
得到密文pjuzvenzkmed1,2012,gzfxdvAkmedijjd'nuzv,(没有处理空格及标点符
号等特殊字符,但加密效果已有)。
为了证明对应的解密是否正确,现进行解密环节,把刚才密文解密,从截图中可以看到当
时加密使用的密钥时zhouxiaoyeah
解密后的字符串跟之前原明文完全一样。
(3)维吉利亚密码
维吉利亚密码由于需要产生一个维吉利亚字母代换表,此处为了学习方便,在程序运行过
程中特意将该表也打印到了屏幕:
输入明文:guoqingjiekuaile,密钥:whutms(此例为课件上一例子)
大全
标准文案
选择解密过程,帮刚才的密文重新翻译成明文:
(4)轮换算法
主要函数介绍
大全
标准文案
凯撒密码:
voidkaisa_de();//解密
voidkaisa_en();//加密
void_kaisa();调用上面两个子函数
单表置换加密:
voiddbzh_alphabeta();//产生代换字符表
voiddbzh_en();//产生密文,即加密
voiddbzh_de();//产生明文,即解密
void_danbiaozhihuan();被main()调用,运行时根据选择调用上面的三个函数
维吉利亚密码:
voidwjly_en();维吉利亚加密函数
voidwjly_de();解密函数
int_weijiliya();调用加密解密函数
轮换法加密:
大全
标准文案
voidlunhuan_en();
voidlunhuan_de();
void_lunhuan();
实验中的问题
(1)各个加密函数之间的基本上完全独立,内部定义了太多的自己变量,从空间上看运行起
来占用空间较大。可以尝试定义几个全局变量,让他们共用。如输入的密文,密钥,产生的明
文等等。
(2)操作不够人性化。由于时间的原因,没有在程序的界面上话太多工夫,比如运行完加密
或者解密过程后,该转到第一个主界面(四个加密算法的选择界面)还是仍然留在当前密码方
法的界面,退出时时直接退出控制台程序还是退出到开始界面。
此外,程序的容错处理还不完善,一下非法输入还不能很友好的处理。
操纵的人性化
四种加密算法源代码:
#include
#include
#include
#include
#include
usingnamespacestd;
#defineMIG_WE1000//设明文长度最大为1000
charmingwen[MIG_WE];//存放明文
charmiwen[MIG_WE];//存放密文
charmiyuejvzi[100];//密钥句子
charalphabeta[27];//代换字母表
stringstr="abcdefghijklmnopqrstuvwxyz";
voidkaisa_de();//解密
voidkaisa_en();//加密
void_kaisa();
voiddbzh_alphabeta();//产生代换字符表
voiddbzh_en();//产生密文
voiddbzh_de();//产生密文
void_danbiaozhihuan();
voidwjly_en();
voidwjly_de();
voidCreate_miyuejvzi(char);
int_weijiliya();
voidlunhuan_en();
voidlunhuan_de();
void_lunhuan();
大全
标准文案
voidmain()
{
intchoice;
printf("n");//起始输出界面
printf("
-----------------------------------------n");
printf("信息管理与信息系统**班nn");
printf("**学号:**n");
while(1)/*循环测试*/
{
printf("n");
printf("
*****************************************n");
printf("n");
printf("|加密解密方法n");
printf("n");
printf("|1、凯撒密码n");
printf("|2、单表置换n");
printf("|3、维吉利亚密码n");
printf("|4、轮换法n");
printf("|5、退出n");
printf("
----------------------------------------n");
printf("请输入1--5进行选择:");
scanf("%d",&choice);
while(choice>5||choice<=0)//如果输入数字不符要求,重新输入,直至正确为
止
{
printf("n请输入选项前面的编号:");
scanf("%d",&choice);
}
switch(choice)//调用不同的解密加密算法
{
case1:_kaisa();break;//凯撒密码
case2:_danbiaozhihuan();break;//单表置换密码
case3:_weijiliya();break;//维吉利亚密码
case4:_lunhuan();break;//轮换法
case5:exit(0);//退出程序
}
system("pause");/*暂停*/
system("cls");/*清屏*/
}
}
//凯撒密码
void_kaisa()
{
intchoice;
大全
标准文案
do
{
system("CLS");
printf("n");
printf("tt凯撒加密nttt请选择操作:n");
printf("ttt1.加密nttt2.解密nttt3.退出n");
printf("_________________________________________________________________
___n");
printf("%15c",'');
printf("注:----恺撒密码按c=(m+9)%%26加密----n");
printf("%19c",'');
printf("----除字母其他字符均按c=(m+1)%%26加密----n");
printf("%19c",'');
printf("----当其他其它字符+1为字母时+26跳过字母加密----n");
printf("%19c",'');
printf("----当其他其它字符+1超出ASCII码表示范围时-128循环表示
----n");
scanf("%d",&choice);
getchar();
if(choice==1)
{
kaisa_en();
break;
}
elseif(choice==2)
{
kaisa_de();
break;
}
elseif(choice==3)
{
printf("n%33c",'');
printf("3:退出n");
exit(0);
}
else
{
printf("输入错误,按任意键继续:n");
getchar();
system("cls");
}
}while(choice!=1||choice!=2);
}
//凯撒加密
voidkaisa_en()//加密
大全
标准文案
{
大全
intleng,i,miyue;
charchc[MIG_WE],chp[MIG_WE];
printf("请输入你要加密的明文:n");
printf("%28c",'');
gets(chc);
printf("请输入密钥(如数字9):");
scanf("%d",&miyue);
leng=strlen(chc);
printf("%28c",'');
printf("密文:n");
printf("%28c",'');
for(i=0;i
{
if(isupper(chc[i]))
{
if(chc[i]+miyue>'Z')
{
chp[i]=chc[i]+miyue-26;
printf("%c",chp[i]);
}
else
{
chp[i]=chc[i]+miyue;
printf("%c",chp[i]);
}
}
elseif(islower(chc[i]))
{
if(chc[i]+miyue>'z')
{
chp[i]=chc[i]+miyue-26;
printf("%c",chp[i]);
}
else
{
chp[i]=chc[i]+miyue;
printf("%c",chp[i]);
}
}
else
{
chp[i]=chc[i]+1;
if(chp[i]=='A'||chp[i]=='a')//遇到+1为字母时的处理
chp[i]+=26;
elseif(chp[i]>127)//遇到+1超出ASCII码表示范围时
chp[i]=char(chp[i]-128);
printf("%c",chp[i]);
}
标准文案
}
printf("n");
}
//凯撒解密
voidkaisa_de()//解密
{
intleng,i,miyue;
charchc[MIG_WE],chp[MIG_WE];
printf("请输入你要解密的密文:n");
printf("%28c",'');
gets(chc);
printf("请输入密钥(如数字9):");
scanf("%d",&miyue);
leng=strlen(chc);
printf("%28c",'');
printf("明文:n");
printf("%28c",'');
for(i=0;i
{
if(isupper(chc[i]))
{
if(chc[i]-miyue<'A')
{
chp[i]=chc[i]-miyue+26;
printf("%c",chp[i]);
}
else
{
chp[i]=chc[i]-miyue;
printf("%c",chp[i]);
}
}
elseif(islower(chc[i]))
{
if(chc[i]-miyue<'a')
{
chp[i]=chc[i]-miyue+26;
printf("%c",chp[i]);
}
else
{
chp[i]=chc[i]-miyue;
printf("%c",chp[i]);
}
}
else
{
chp[i]=chc[i]-1;
大全
标准文案
if(chp[i]=='Z'||chp[i]=='z')//遇到-1为字母时的处理
chp[i]-=26;
elseif(chp<0)//遇到-1超出ASCII码表示范围时
chp[i]=char(chp[i]+128);
printf("%c",chp[i]);
}
}
printf("n");
}
/////单表置换加密
void_danbiaozhihuan()
{
system("CLS");
intchoice;
printf("n");
printf("tt单表置换加密nttt请选择操作:n");
printf("ttt1.加密nttt2.解密nttt3.退出n");
scanf("%d",&choice);
if(choice==1)
{
printf("请输入你想加密的字符串(请不要超出%d个字符,不能输入中
文):",MIG_WE);
getchar();
gets(mingwen);
printf("你输入的明文是:%sn",mingwen);
intmingwen_length=strlen(mingwen);//明文长度
dbzh_alphabeta();//产生代换字符表
dbzh_en();//加密
}
if(choice==2)
{
printf("请输入你想解密的字符串:");
getchar();
gets(miwen);
printf("你输入的密文是:%sn",miwen);
intmiwen_length=strlen(miwen);//密文长度
dbzh_alphabeta();//产生代换字符表
dbzh_de();
}
}
//单表置换产生代换字符表
voiddbzh_alphabeta()
{
inti,j;
大全
标准文案
printf("请输入密钥句子,至少为1个字符,最多100个字符,且第一个字符必须是小
写字母:n");
gets(miyuejvzi);//输入的密钥句子,至少为1个字符,最多100个字符,且第一个
必须为字母
printf("%s",miyuejvzi);
intlength=strlen(miyuejvzi);
intpos=0;//指示填充位置
inttag=1;//
alphabeta[0]=miyuejvzi[0];//填充第0个位置
for(i=1;i
{
if(isalpha(miyuejvzi[i])!=0)//是字母
{
tag=1;
for(j=0;j<=pos;j++)
{
if(alphabeta[j]==miyuejvzi[i])//alphabet表中已经存在字母
miyuejvzi[i]
{
tag=0;
break;
}
}
if(tag==1)
alphabeta[++pos]=miyuejvzi[i];
}
}
for(i=0;i<26;i++)//把英文字母表中还没有出现在代换字母表中的字母存入代换字
母表
{
tag=1;
for(j=0;j<=pos;j++)
{
if(alphabeta[j]==str[i])//alphabet表中已经存在英文字母表中的第i个
字母
{
tag=0;
break;
}
}
if(tag==1)
alphabeta[++pos]=str[i];
}
cout<<"原始字母表为"<
大全
标准文案
cout<<"代换密码表为"<
}
//单表置换加密
voiddbzh_en()//产生密文
{
//对明文中的每一个字母加密
//计算出该字母在字母表中的序号,a序号为0,b序号为1...,依次类推
//alphabeta[0]是序号为0的字母a的密文,alphabeta[1]是序号为1的字母的密
文...,依次类推
intpos;
for(inti=strlen(mingwen);i>=0;i--)
{
if(islower(mingwen[i]))//假如当前字符是小写字母
{
pos=mingwen[i]-'a';//计算出当前字母在字母表中的序号
miwen[i]=alphabeta[pos];
}
else//不是字母,原样复制
miwen[i]=mingwen[i];
}
printf("明文为:%sn",mingwen);
printf("密文为:%sn",miwen);
}
//单表置换解密(产生明文)
voiddbzh_de()
{
for(inti=strlen(miwen);i>=0;i--)
{
if(islower(miwen[i]))//假如当前字符是小写字母
{
for(intj=0;j<26;j++)
{
if(miwen[i]==alphabeta[j])//当前密文字符,在代换字符表的第j
个位置,在其明文字符为str[j];
{
mingwen[i]=str[j];
break;
}
}
}
else//不是字母,原样复制
mingwen[i]=miwen[i];
}
printf("密文为:%sn",miwen);
printf("明文为:%sn",mingwen);
}
大全
标准文案
//////维吉尼亚加密
int_weijiliya()
{
system("CLS");
inti,j;
char*alphabet="abcdefghijklmnopqrstuvwxyz";
charvtable[26][26];
printf("vigeneretablen");
printf("t%sn",alphabet);
for(i=0;i<26;i++){
printf("n%c",*alphabet);//
for(j=0;j<26;j++){
if(*alphabet+j<=122)
{vtable[i][j]=*alphabet+j-32;printf("%c",vtable[i][j]);}
else
{vtable[i][j]=*alphabet+j-58;printf("%c",vtable[i][j]);}
}
*alphabet++;
printf("n");
}
intchoice;
printf("n");
printf("ttvigenere密码(本算法规定:明文为小写字母,密文为大写字
母)nttt请选择操作:n");
printf("ttt1.加密nttt2.解密nttt3.退出n");
scanf("%d",&choice);
switch(choice)
{
case1:
printf("请输入明文(小写字母):");
getchar();
gets(mingwen);
printf("请输入密钥:");
gets(miyuejvzi);
wjly_en();//加密
break;
case2:
printf("请输入密文(大写字母):");
getchar();
gets(miwen);
printf("请输入密钥:");
gets(miyuejvzi);
wjly_de();//解密
break;
case3:
break;
}
大全
标准文案
return0;
}
//维吉利亚加密
voidwjly_en()
{
unsignedintmiyuejvzi_length,mingwen_length,i,j,d,mod;
miyuejvzi_length=strlen(miyuejvzi);
mingwen_length=strlen(mingwen);
d=mingwen_length/miyuejvzi_length;//d为明文长度除密钥长度后去整
mod=mingwen_length%miyuejvzi_length;//mod为取余
if(d>0){
for(i=1;i
for(j=0;j
miyuejvzi[i*miyuejvzi_length+j]=miyuejvzi[j];
}
for(i=0;i
miyuejvzi[d*miyuejvzi_length+i]=miyuejvzi[i];
}
for(i=0;i
if(mingwen[i]+miyuejvzi[i]-'a'>122)
miwen[i]=mingwen[i]+miyuejvzi[i]-'a'-32-26;
else
miwen[i]=mingwen[i]+miyuejvzi[i]-'a'-32;
}
}
else{
for(i=0;i
if(mingwen[i]+miyuejvzi[i]-'a'>122)
miwen[i]=mingwen[i]+miyuejvzi[i]-'a'-32-26;
else
miwen[i]=mingwen[i]+miyuejvzi[i]-'a'-32;
}
}
printf("明文是:%sn",mingwen);
printf("密钥是:%sn",miyuejvzi);
printf("密文是:%sn",miwen);
}
//维吉利亚解密
voidwjly_de()
{
unsignedintmiyuejvzi_length,miwen_length,i,j,d,mod;
miyuejvzi_length=strlen(miyuejvzi);
miwen_length=strlen(miwen);
d=miwen_length/miyuejvzi_length;//d为密文长度除密钥长度后去整
mod=miwen_length%miyuejvzi_length;//mod为取余
大全
标准文案
if(d>0){
for(i=1;i
for(j=0;j
miyuejvzi[i*miyuejvzi_length+j]=miyuejvzi[j];
}
for(i=0;i
miyuejvzi[d*miyuejvzi_length+i]=miyuejvzi[i];
}
for(i=0;i
if(miwen[i]+32-miyuejvzi[i]>=0)
mingwen[i]=miwen[i]-miyuejvzi[i]+32+'a';
else
mingwen[i]=miwen[i]-miyuejvzi[i]+32+'a'+26;
}
}
else
{
for(i=0;i
if(miwen[i]+32-miyuejvzi[i]>=0)
mingwen[i]=miwen[i]-miyuejvzi[i]+32+'a';
else
mingwen[i]=miwen[i]-miyuejvzi[i]+32+'a'+26;
}
}
printf("密文是:%sn",miwen);
printf("密钥是:%sn",miyuejvzi);
printf("明文是:%sn",mingwen);
}
//转换加密
voidlunhuan_en()
{
charData[50];
charShade[50];//存取密文
intdlg,i,j,m,cnt,k;
for(i=0;i<50;i++)
{
Data[i]='0';
}
printf("请输入明文!n");
fflush(stdin);
gets(Data);
dlg=strlen(Data);
for(i=0;i
{
if(Data[i]=='')
{
for(k=i+1;k
{
大全
标准文案
Data[k-1]=Data[k];
}
dlg--;
i--;
}
else
if((Data[i]<'A'||Data[i]>'Z')&&(Data[i]<'a'||Data[i]>'z'))
{
printf("你输入的明文不正确!n");
break;
}
else
if(Data[i]>='A'&&Data[i]<='Z')
{
Data[i]+=32;
}
}
printf("n明文是:");
puts(Data);
cnt=(dlg-1)/5+1;
for(i=dlg;i
{
Data[i]='0';
}
m=0;
for(i=0;i<5;i++)
{
for(j=0;j
{
if(Data[i+5*j]=='0')
{
m--;
}
else
{
Shade[m]=Data[i+5*j];
}
m++;
}
}
Shade[dlg]='0';
printf("n密文是:");
puts(Shade);
printf("n");
}
//////轮换解密
voidlunhuan_de()
{
大全
标准文案
大全
inti,j,slg,m,cnt,k=0;
charshade[50];
charshow[50];
for(i=0;i<50;i++)
{
shade[i]='0';
}
printf("n请输入密文!n");
fflush(stdin);
gets(shade);
slg=strlen(shade);
for(i=0;i
{
if(shade[i]=='')
{
printf("n本系统译文不支持空格!请重新输入!");
}
else
if((shade[i]<'A'||shade[i]>'Z')&&(shade[i]<'a'||shade[i]>'z'))
{
printf("n你输入的密文不正确!n");
}
else
if(shade[i]>='A'&&shade[i]<='Z')
{
shade[i]+=32;
}
}
printf("n输入的密文是:");
puts(shade);
cnt=(slg-1)/5+1;
for(i=slg;i<5*cnt;i++)
{
shade[i]='0';
}
m=0;
if(slg%5==1)
{
for(i=0;i
{
show[i*5]=shade[k];
k++;
m=k-1;
}
for(j=1;j<5;j++)
{
for(i=0;i
{
show[i*5+j]=shade[m+1];
标准文案
m++;
}
}
m=0;k=0;
}
elseif(slg%5==2)
{
for(j=0;j<2;j++)
{
for(i=0;i
{
show[i*5+j]=shade[k];
k++;
m=k-1;
}
}
for(j=2;j<5;j++)
{
for(i=0;i
{
show[i*5+j]=shade[m+1];
m++;
}
}
}
else
{
for(i=0;i
{
for(j=0;j<5;j++)
{
if(shade[j*cnt+i]=='0')
{
}
else
{
show[m]=shade[j*cnt+i];
m++;
}
}
}
}
show[slg]='0';
printf("n明文是:");
puts(show);
printf("n");
}
void_lunhuan()//只实现先行后列的方法
大全
标准文案
{
}
intchoice;
system("CLS");
printf("n");
printf("tt轮换加密nttt请选择操作:n");
printf("ttt1.加密nttt2.解密nttt3.退出n");
fflush(stdin);
scanf("%d",&choice);
switch(choice)
{
case1:
case'a':
lunhuan_en();
break;
case2:
lunhuan_de();
break;
default:
break;
}
---------------------------------------------------------------------------------
------------------------------------------
实验报告评语及成绩(请按优,良,中,及格,不及格五级评定)
成绩:
教师签字:
大全
标准文案
实验项目名称进程管理实验
实验者
同组者
**专业班级
无
**
实验成绩
组别
实验日期2012年03月15日
第一部分:实验预习报告
1、实验目的、意义
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
2、实验基本原理与方法
进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)
和先来先服务算法。
每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优
先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到
达时间为进程输入的时间。
每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之
一就绪进程获得CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
进程的运行时间以时间片为单位进行计算。如果运行一个时间片后,进程的已占用CPU
时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间
还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低
一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行
检查。重复以上过程,直到所要进程都完成为止。
3、主要仪器设备及耗材
实验室提供计算机和上网条件,C语言上机环境。
4、实验方案与技术路线(综合性、设计性实验)
大全
标准文案
第二部分:实验过程记录
实验原始记录(包括实验数据记录,实验现象记录,实验过程发现的问题等)
1.原理分析
(1)假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格
式为:
进程名
指针
要求运行时间
优先数
状态
其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。
指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首
地址,最后一个进程中的指针为“0”。
要求运行时间——假设进程需要运行的单位时间数。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就
绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。
(2)在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和
“要求运行时间”。
(3)为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进
程,用指针指出队列的连接情况。例:
队首标志
K2
K1P1
0
2
1
R
PCB1
K2P2
K4
3
5
R
PCB2
K3P3
K5
1
3
R
PCB3
K4P4
K3
2
4
R
PCB4
K5P5
K1
4
2
R
PCB5
(4)处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先
数就减“1”。由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而
是执行:
优先数-1
要求运行时间-1
来模拟进程的一次运行。
提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它
占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。
(5)进程运行一次后,若要求运行时间0,则再将它加入队列(按优先数大小插入,且置
大全
标准文案
队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。
(6)若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程
都成为“结束”状态。
(7)在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及
运行一次后进程队列的变化。
(8)为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,
显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
2.主要模块
(1)数据结构设计
定义进程控制块:
structpcb{
charname[10];//进程名
charstate;//进程状态
intsuper;//它的前一个运行的进程
intntime;//进程运行完成所需时间
intrtime;//当前进程已运行的时间
structpcb*link;//下一个要执行的进程
};
(2)功能函数(忽略返回值及参数)
Input():用于建立进程控制块。主要通过输入各进程信息,然后根据sort()进行优先级排
序。
Sort():进程优先级排序函数。通过建立链表来将各进程按照优先级高到低排好序。
Running():进程运行时间到,置就绪状态(不考虑资源)。
Check():进程查看函数。用于查看当前运行的进程和就绪队列中的进程。
Disp():专门用于显示当前进程。由check()调用。
大全
标准文案
第三部分结果与讨论(可加页)
实验结果分析(包括数据处理、实验现象分析、影响因素讨论、综合分析和结论等)
程序设计类实验:包括源程序、输入数据、运行结果、实验过程发现的问题及解决方法等;
分析与设计、软件工程类实验:编制分析与设计报告,要求用标准的绘图工具绘制文档中
的图表。系统实施部分要求记录核心处理的方法、技巧或程序段;
其它实验:记录实验输入数据、处理模型、输出数据及结果分析
1.输入与输出
(1)在模拟一开始需要数据进程的个数,然后依次输入进程名,它的优先级别(整数),
(2)数据这一次录入后,以后就不需要输入,只需回车不断查看“进程”执行的情况。
(3)以后回车每次输出当前正在“运行”的“进程”和就绪队列中的情况,包括进程名、状态、
优先级别、总共所需实际和已经运行多久。
2.运行结果截图及分析
大全
标准文案
某一录入的数据:
进程名
优先级别
运行时间
状态
进程0
Pcb1
2
1
R
进程1
Pcb2
3
5
R
进程2
Pcb3
1
3
R
进程3
Pcb4
2
4
R
进程4
Pcb5
4
2
R
第一次执行时,由于pcb5的优先级是4,为最高,故先它先执行。如下图:
回车,执行第二次。由于pcb5还未完成,故优先级降1,与pcb2同级,然后pcb2要早于
pcb5到达,所以当前运行的时pcb2,pcb5进入就绪队列:
大全
标准文案
同理,到了第三次,pcb2还需要运行5-1=4个单位时间,优先级降1,pcb5重新又获得占
用“CPU”,一个单位时间后,pcb5正好运行完成:
以后的执行情况同理,剩下的进程中又三个处于2级,但pcb1最先到达,所以第四次执
行进程pcb1(运行1次即可完成):
经过实际运行发现,总够15次后,pcb2最后一个运行完成:
大全
标准文案
3.源程序及注释
#include
#include
#include
#definegetpch(type)(type*)malloc(sizeof(type))
#defineULL0
structpcb{/*定义进程控制块PCB*/
charname[10];//进程名
charstate;//进程状态
intsuper;//它的前一个运行的进程
intntime;
intrtime;
structpcb*link;
}*ready=ULL,*p;
typedefstructpcbPCB;
voidsort()/*建立对进程进行优先级排列函数*/
{
PCB*first,*second;
intinsert=0;
if((ready==ULL)||((p->super)>(ready->super)))/*优先级最大者,插入队首
*/
{
p->link=ready;
ready=p;
}
else/*进程比较优先级,插入适当的位置中*/
{
first=ready;
second=first->link;
while(second!=ULL)
{
if((p->super)>(second->super))/*若插入进程比当前进程优先数
大,*/
{/*插入到当前进程前面*/
p->link=second;
first->link=p;
second=ULL;
insert=1;
}
else/*插入进程优先数最低,则插入到队尾*/
{
first=first->link;
second=second->link;
}
}
大全
标准文案
if(insert==0)first->link=p;
}
}
voidinput()/*建立进程控制块函数*/
{
inti,num;
system("cls");/*清屏*/
printf("n请输入要模拟的进程个数:");
scanf("%d",&num);
for(i=0;i
{
printf("n进程%d:n",i);
p=getpch(PCB);
printf("n请输入进程名:");
scanf("%s",p->name);
printf("n请输入优先级别:");
scanf("%d",&p->super);
printf("n输入它的运行时间:");
scanf("%d",&p->ntime);
printf("n");
p->rtime=0;p->state='w';
p->link=ULL;
sort();/*调用sort函数*/
}
}
intspace()
{
intl=0;PCB*pr=ready;
while(pr!=ULL)
{
l++;
pr=pr->link;
}
return(l);
}
voiddisp(PCB*pr)/*建立进程显示函数,用于显示当前进程*/
{
printf("n进程名状态级别总共所需时间已运行时间n");
printf("|%st",pr->name);
printf("%ct",pr->state);
printf("%dt",pr->super);
printf("%dtt",pr->ntime);
printf("%dt",pr->rtime);
printf("n");
}
voidcheck()/*建立进程查看函数*/
大全
标准文案
{
PCB*pr;
printf("n****当前运行的进程是:%s",p->name);/*显示当前运行进程*/
disp(p);
pr=ready;
printf("n****就绪队列中的进程有:n");/*显示就绪队列状态*/
while(pr!=ULL)
{
disp(pr);
pr=pr->link;
}
}
voiddestroy()/*建立进程撤消函数(进程运行结束,撤消进程)*/
{
printf("n进程[%s]执行完毕!n",p->name);
free(p);
}
voidrunning()/*建立进程就绪函数(进程运行时间到,置就绪状态*/
{
(p->rtime)++;
if(p->rtime==p->ntime)
destroy();/*调用destroy函数*/
else
{
(p->super)--;
p->state='w';
sort();/*调用sort函数*/
}
}
voidmain()/*主函数*/
{
intlen,h=0;
input();
len=space();
while((len!=0)&&(ready!=ULL))
{
getchar();
h++;
printf("n执行次数:%dn",h);
p=ready;
ready=p->link;
p->link=ULL;
p->state='R';
check();
running();
printf("n回车继续执行……");
大全
标准文案
}
getchar();
}
printf("nn全部进程执行完毕!n");
getchar();
4.结论
本程序实现了“最高优先数优先”调度算法,“最高优先数优先”调度算法的基本思想是
把CPU分配给就绪队列中优先数最高的进程。静态优先数是在创建进程时确定的,并在整个进
程运行期间不再改变。动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且
可以按一定原则修改优先数。动态优先数算法比静态优先数算法更先进,可防止一个长作业长
期的垄断处理机。
---------------------------------------------------------------------------------
------------------------------------------
实验报告评语及成绩(请按优,良,中,及格,不及格五级评定)
成绩:
教师签字:
大全
标准文案
大全
本文发布于:2022-08-01 16:31:22,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/falv/fa/82/50871.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |