標準文案
學生學號***實驗課成績
學生實驗報告書
實驗課程名稱
開課學院
指導教師姓名
學生姓名
學生專業班級
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)各個加密函數之間的基本上完全獨立,內部定義了太多的自己變量,從空間上看運行起
來占用空間較大??梢試L試定義幾個全局變量,讓他們共用。如輸入的密文,密鑰,產生的明
文等等。
(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.newhan.cn/falv/fa/82/50871.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
| 留言與評論(共有 0 條評論) |