操作系统课程设计报告书+文件加密存储


目录

一、设计简介…………………………………………………………

课程设计题目………………………………………………………………………

课程设计小组成员…………………………………………………………………

二、        设计目的……………………………………………………

三、        设计意义……………………………………………………

四、        设计要求……………………………………………………

五、        设计内容……………………………………………………

六、        程序流程图…………………………………………………

七、        程序源代码…………………………………………………

八、        程序运行结果分析…………………………………………

九、        系统调用……………………………………………………

十、        心得体会……………………………………………………

参考文献……………………………………………………………

一、设计简介:

设计课题:文件加密存储

二、设计目的:

有时我们有些资料不希望别人看到,最常用的方法就是加密。对给定的相关文件进行加密可以对文件进行保护,可以防止某些重要信息不被别人所知道甚至窃取。对文件起到保护作用,可以方便用户使用某些只有自己能知道的信息,能够安全保护文件的相关内容几信息不被外流。随着信息社会的到来,人们在享受信息资源所带来的巨大的利益的同时,也面临着信息安全的严峻考验。信息安全已经成为世界性的现实问题,信息安全问题已威胁到国家的政治、经济、军事、文化、意识形态等领域,同时,信息安全问题也是人们能否保护自己的个人隐私的关键。信息安全是社会稳定安全的必要前提条件。

三、设计意义:

至今,密码技术是取得信息安全性最有效的一种方法, 密码技术是信息安全的核心技术。通过数据加密,人们可以有效地保证通信线路上的内容不被泄露,而且还可以检验传送信息的完整性。进一步,密码技术可以应用于数字签名、身份认证和信息鉴定,这些应用对于资源存取控制以及其它安全措施是必须而且有效的。相对于防病毒软件和防火墙软件来说,基于密码技术密码类产品、认证类产品份额相对较小,但随着金融、电信、政府等行业信息化建设对于网络安全整体解决方案需求的增加,将会有较大的增长。

四、设计要求:

利用文件系统的系统调用编程对文件的内容进行加、解密。要求程序从环境的命令行携带4个参数。第一是文件名,第二个是操作方式,第三个是密钥,第四个是加密钥循环使用长度。其中后两个参数是可以忽略,但对忽略的情况要提供缺省值。要求最后实现对文件的加密转储,或通过改道的办法进行转储。对于已加密的文件可以进行解密显示或解密后转储。建议加密过程使用按字符进行异或的方式处理,你也可提供自己的加密方式。

五、设计内容:

加密技术是依靠加密算法对原始文档进行编码形成密文从而达到加密目的。加密算法就是通过一组密钥对原始信息(明文)进行一系列的数学运算得到另外一组信息(密文),这就是加密过程。采用同样的算法和同样的密钥,可以从密文算回原始信息(明文),这就是解密过程。

本设计采用按字符异或的加密算法对文档进行加密形成密文,而后,用同样的算法配合密钥和密钥循环长度可以对密文进行解密。程序从命令行携带文件名(in)、操作方式(Op)、密钥(pwd)、加密钥循环使用长度(length)四个参数,其中pwd和length可以忽略,程序为忽略的情况提供了缺省值。若命令行带入的参数少于两个,即没有参数或只有第一个参数,程序提供了输入块对四个参数进行输入。

六、程序流程图:

 

 

七、程序源代码:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void jiami(char *in,char *pwd,int length);   /*函数声明*/

void jiemi(char *in,char *pwd,int length);   /*函数声明*/

int main(int argc,char *argv[])

{

 char in[30];          /*需要加密或解密的文件名*/

 int length;            /*加密钥循环使用长度*/

 char pwd[8];        /*加密钥*/

 char Op[10];        /*操作方式*/

if(argc<3)             /*如果从命令行带入的参数少于两个,刚提示输入*/

{

    printf("You must enter filename and Operation mode!\n");

    printf("Input filename:\n");

    scanf("%s",in);

    printf("Input Operation mode:\n");

    scanf("%s",Op);

    printf("Enter password:\n");

    scanf("%s",pwd);

    printf("Input length:\n");

    scanf("%d",&length);

}

else

    {

        if(argc==3)     /*命令行带两个参数,后两个忽略,则给后两个参数提供缺省值pwd[]="00000000",length=8*/

        {

            strcpy(in,argv[1]);

            strcpy(Op,argv[2]);

            strcpy(pwd,"00000000");

            length=8;

        }

        else if(argc==4)     /*若从命令行带入三个参数,刚对length提供缺值8*/

             {

                strcpy(in,argv[1]);

                strcpy(Op,argv[2]);

                strcpy(pwd,argv[3]);

                length=8;

             }

             else

             {

                strcpy(in,argv[1]);

                strcpy(Op,argv[2]);

                strcpy(pwd,argv[3]);

                length=(int)argv[4]-48;

             }

    }

if(strcmp("jiami",Op)==0)

        jiami(in,pwd,length);            /*调用加密*/

else if(strcmp("jiemi",Op)==0)

        jiemi(in,pwd,length);            /*调用解密*/

     else

        printf("Input error!");

}

void jiami(char *in,char *pwd,int length)    /*加密*/

{

 FILE *fp1,*fp2;

 register char ch;

 int j=0;

 fp1=fopen(in,"rb");                          /*为输入打开一个二进制文件*/

 if(fp1==NULL)

 {

  printf("Cannot open in-file!\n");

  exit(1);

 }

 fp2=fopen("encryption_file","wb");          /*为读写建立一个新的二进制文件*/

 if(fp2==NULL)

 {

  printf("Cannot open or create output-file!\n");

  exit(1);

 }

 ch=fgetc(fp1);

 while(!feof(fp1))

 {

  fputc(ch^pwd[j>=length?j=0:j++],fp2);           /*按字符异或加密*/

  ch=fgetc(fp1);

 }

 fclose(fp1);

 fclose(fp2);

}

void jiemi(char *in,char *pwd,int length)       /*解密*/

{

 FILE *fp1,*fp2;

 register char ch;                         /*寄存器变量ch */

 int j=0;

 fp1=fopen(in,"rb");                          /*为输入打开一个二进制文件*/

 if(fp1==NULL)

 {

  printf("Cannot open in-file!\n");

  exit(1);

 }

 fp2=fopen("crack_file.txt","wb");             /*为读写建立一个新的二进制文件*/

 if(fp2==NULL)

 {

  printf("Cannot open or create output-file!\n");

  exit(1);

 }

 ch=fgetc(fp1);

 while(!feof(fp1))

 {

  fputc(ch^pwd[j>=length?j=0:j++],fp2);           /*按加密方法进行解密*/

  ch=fgetc(fp1);

 }

 fclose(fp1);

 fclose(fp2);

}

八、程序运行结果分析:

cc jiami.c编译程序,

1、用./a.out(不带参数或参数个数小于两个)运行程序,程序提示需要输入文件名和操作方式,按提示进行参数输入,程序运行,按操作要求对目标文件进行加密解密操作,若文件不存在或打开失败,则操作失败,给出Cannot open in-file! 提示,程序结束;

2、用./a.out 文件名 操作方式(带两个参数) 运行程序,忽略后两个参数,程序为后两个参数提供缺省值,密钥为“00000000”,循环长度为8;

3、用./a.out 文件名 操作方式 密钥(带三个参数)运行程序,则程序为最后一个参数密钥循环使用长度设置缺省值8;

4、用./a.out 文件名 操作方式 密钥 加密钥循环使用长度(带四个参数),程序按用户所提供的参数值运行;

不管用哪种方式运行程序,若给出的文件不存在或打开失败,则操作(加密或解密)失败; 加密或解密时,若密文文件encryption_file或解密后的文档crack_file.txt已存在,则程序会删除原有文件用新文件替换; 加密过程采用按字符异或的方式处理。

程序改进方案:

       1、本程序采用的按字符异或加密的算法是一种比较简单的加密算法,安全性较差,若对文件保密性要求比较高,则可采用一些复杂的算法进行加密。

       2、本程序入口只能输入要加密或解密的目标文件名,而对加密或解密后的文件不能自定义,只能用程序提供的encryption_file和crack_file.txt存放文件,这样,当对同一目录下多个文档加密时,加密解密操作后的文件会替换原来的文件,造成数据丢失;

九、系统调用:

int main(int argc,char *argv[])

argc 是外部命令参数的个数,argv[] 存放各参数的内容.在运行程序以后,操作系统会自动将参数传给你。例如编译好的程序叫做program.exe 你运行program a b 这个时候,argc = 3 argv[0] = "program" argv[1] = "a" argv[2] = "b"

fopen ( string filename, string mode)

fopen函数用来打开一个文件,其调用的一般形式为:文件指针名=fopen(文件名,使用文件方式); 其中,“文件指针名”必须是被说明为FILE 类型的指针变量; “文件名”是被打开文件的文件名;“使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。

文件使用方式意义:

“rt” 只读打开一个文本文件,只允许读数据
“wt” 只写打开或建立一个文本文件,只允许写数据
“at” 追加打开一个文本文件,并在文件末尾写数据
“rb” 只读打开一个二进制文件,只允许读数据
“wb” 只写打开或建立一个二进制文件,只允许写数据
“ab” 追加打开一个二进制文件,并在文件末尾写数据
“rt+” 读写打开一个文本文件,允许读和写

“wt+” 读写打开或建立一个文本文件,允许读写
“at+” 读写打开一个文本文件,允许读,或在文件末追加数据
“rb+” 读写打开一个二进制文件,允许读和写
“wb+” 读写打开或建立一个二进制文件,允许读和写
“ab+” 读写打开一个二进制文件,允许读,或在文件末追加数据

fputc(char ch,FILE *fp);

作用: 把一个字符写到磁盘文件上去,即将字符ch输出到fp所指向的文件中去。

返回值:   成功:返回值就是输出的字符;

       失败:返回EOF(-1)。

fgetc(FILE *fp);

作用:从指定的文件读入一个字符,即从fp所指向的文件中读入一个字符。

返回值:   成功:返回值所得到的字符;

       失败:返回EOF(-1)。

feof(FILE *fp)

作用:检查文件是否结束。

返回值: 遇文件结束符返回非零值,否则返回0

心得体会

作为计算机类本科生教学的主要基础课之一,课程紧密结合计算机课程类的专业特点,系统介绍操作系统的基本知识,基本组成,体系结构和工作模式,从而使学生能较清楚地了解操作系统的知识,建立起系统的概念。

 这次操作系统课程设计用时一个星期,在整整一星期的日子里,可以说得是大家积极努力准备,同时可以学到很多很多的的东西,不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。以前,在写一个程序的时候,我总是不细心,怕很浪费时间。但是,这次课程设计完全改变了我以前的那种错误的认识,以前我接触的那些程序都是很短、很基础的,但是在课程设计中碰到的那些需要很多代码才能完成的任务,在做设计的过程中,我们每一步要做什么,每一步要完成什么任务都有一个很清楚的思路,

其次,以前对于编程工具的使用还处于一知半解的状态上,但是经过一段上机的实践,对于怎么去排错、查错,怎么去看每一步的运行结果,确保程序的正确性上都有了很大程度的提高。

 通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。

 这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在同学和老师的辛勤指导下,终于游刃而解。

参考文献:

1、谭浩强·《C程序设计》(第三版)·清华大学出版社,2005

2、严蔚敏,吴伟民编著·《数据结构》(C语言版)·清华大学出版社,2007

3、张尧学,史美林,张高编著·《计算机操作系统教程》(第3版)·清华大学出版社,2006

 

第二篇:操作系统课程设计--请求页式存储管理

操作系统课程设计

操作系统课程设计

请求页式存储管理

学院: 学号:

姓名: 辅导老师:

1

操作系统课程设计请求页式存储管理

操作系统课程设计

设计四:

1.设计目的

请求页式管理是一种常用的虚拟存储管理技术。本设计通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。

2.设计内容:

通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: ① 50% 的指令是顺序执行的;

② 25% 的指令是均匀分布在前地址部分;

③ 25% 的指令是均匀分布在后地址部分。

具体的实施方法是:

①在 [0,319] 的指令地址之间随机选取一起点 m;

②顺序执行一条指令;

③在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为 m′;

④顺序执行一条指令,其地址为 m′+1;

⑤在后地址 [m′+2,319] 中随机选取一条指令并执行 ;

⑥重复上述步骤② ~ ⑤ , 直到执行 320 次指令。

将指令序列变换成为页地址流

设:①页面大小为 1K;

②用户内存容量为 4 页到 32 页 ;

③用户虚存容量为 32K 。

在用户虚存中,按每 K 存放 10 条指令排列虚存地址,即 320 条指令在虚存中的存放方式为:

第 0 条 ~ 第 9 条指令为第 0 页 ( 对应虚存地址为 [0,9]);

第 10 条 ~ 第 19 条指令为第 1 页 ( 对应虚存地址为 [10,19] ) ;

第 310 条 ~ 第 319 条指令为第 31 页 ( 对应虚存地址为 [310,319]) 。 按以上方式,用户指令可组成 32 页。

计算并输出下述各种算法在不同内存容量下的命中率。

2

操作系统课程设计

先进先出的算法 (FIFO);最近最少使用算法 (LRR);

最少访问页面算法 (LFR);最近最不经常使用算法 (NUR)。

3.实验环境

每个学生一台微机,需要安装windows98或windows2000操作系统,配备VC、VB、java或C编程语言,每个学生上机时间不少于24个小时。

(1)、分页请求系统

是:

(1)请求分页的页表机制。它是在分页的页表机制上增加若干个项而形成的,作为请求分页的数据结构;

(2)缺页中断机构。每当用户程序要访问的页面尚未调入内存时,便产生一缺页中断,以请求OS将所缺的页面调入内存;

(3)地址变换机构。它同样是在分页的地址变换机构的基础上发展形成的。

为了实现请求调页还须得到OS的支持,在实现请求调页功能时,石油OS将所需的页从外存调入内存;在实现置换功能时,也是由OS将内存的某些页调至外存。 为了能实现请求调页和置换功能,系统必须提供必要的硬件支持,其中,最重要的

4.实验提示

提示:A.命中率=1-页面失效次数/页地址流长度

B.本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。

C.关于随机数产生方法,采用TC系统提供函数RAND()和RANDOMIZE()来产生。

5.自己对算法的理解

㈠ FIFO页面置换算法

⑴原理简述

①在分配内存页面数(AP)小于进程页面数(PP)时,当然是最先运行的AP个页面放入内存。

②这时有需要处理新的页面,则将原来内存中的AP个页面最先进入的调出(是以称为FIFO),然后将新页面放入。

③以后如果再有新页面需要调入,则都按⑵的规则进行。

算法特点:所使用的内存页面构成一个队列。

㈡ LRU页面置换算法

3

操作系统课程设计

⑴原理算述

①当分配内存页面数(AP)小于进程页面数(PP)时,当然是把最先执行的AP个页面放入内存。

②当需要调页面进入内存,而当前分配的内存页面全部不空闲时,选择将其中最长时间没有用到的那个页面调出,以空出内存来放置新调入的页面(称为LRU)。 算法特点:每个页面都有属性来表示有多长时间未被CPU使用的信息。 ㈢LFU即最不经常使用页置换算法 ⑴ 原理简述

要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。

LRU算法的硬件支持

把LRU算法作为页面置换算法是比较好的,它对于各种类型的程序都能适用,但1.一个进程在内存中的各个页面各有多久时间未被进程访问;

2.如何快速地知道哪一页最近最久未使用的页面。为此,须利用以下两类支持硬件: 实现起来有相当大的难度,因为它要求系统具有较多的支持硬件。所要解决的问题有:

(1)寄存器

操作系统课程设计请求页式存储管理

(2)栈

可利用一个特殊的栈来保存当前使用的各个页面的页面号。每当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶。

4

操作系统课程设计

算法特点:LFU算法并不能真正反映出页面的使用情况,因为在每一时间间隔内,只是用寄存器的一位来记录页的使用情况,因此,访问一次和访问10000次是等效的。

㈣ NUR页面置换算法

⑴原理简述

所谓“最近未使用”,首先是要对“近”作一个界定,比如CLEAR_PERIOD=50,便是指在CPU最近的50次进程页面处理工作中,都没有处理到的页面。那么可能会有以下几种情况:

①如果这样的页面只有一个,就将其换出,放入需要处理的新页面。

②如果有这样的页面不止一个,就在这些页面中任取一个换出(可以是下标最小的,或者是下标最大的),放入需要处理的页面。

③如果没有一个这样的页面,就随意换出一个页面(可以是下标最小的,或者是下标最大的)。

算法特点:有一个循环周期,每到达这个周期,所有页面存放是否被CPU处理的信息的属性均被置于初始态(没有被访问)。

6.实验流程图

5

操作系统课程设计

7. 实验运行结果

操作系统课程设计请求页式存储管理

6

操作系统课程设计

操作系统课程设计请求页式存储管理

7

操作系统课程设计请求页式存储管理

操作系统课程设计请求页式存储管理

操作系统课程设计

等等。

8. 实验源程序

#include<iostream>

#include<time.h>

using namespace std;

const int MaxNum=320;//指令数

const int M=5;//内存容量

int PageOrder[MaxNum];//页面请求

int Simulate[MaxNum][M];//页面访问过程

int PageCount[M],LackNum;//PageCount用来记录LRU算法中最久未使用时间,LackNum记录缺页数

float PageRate;//命中率

int PageCount1[32];

bool IsExit(int i)//FIFO算法中判断新的页面请求是否在内存中 {

bool f=false;

for(int j=0;j<M;j++)

{

8

操作系统课程设计请求页式存储管理

操作系统课程设计

if(Simulate[i-1][j]==PageOrder[i])//在前一次页面请求过程中寻找是否存在新的页面请求

{

f=true;

}

}

return f;

}

int IsExitLRU(int i)//LRU算法中判断新的页面请求是否在内存中 {

int f=-1;

for(int j=0;j<M;j++)

{

if(Simulate[i-1][j]==PageOrder[i])

{

f=j;

}

}

return f;

}

int Compare()//LRU算法找出内存中需要置换出来的页面

{

int p,q;

p=PageCount[0];

q=0;

for(int i=1;i<M;i++)

{

9

操作系统课程设计

if(p<PageCount[i])

{

p=PageCount[i];

q=i;

}

}

return q;

}

void Init() //初始化页框

{

for(int k=0;k<MaxNum;k++)

{

int n=rand()%320;//随机数产生320次指令

PageOrder[k]=n/10;//根据指令产生320次页面请求 }

for(int i=0;i<MaxNum;i++)//初始化页面访问过程 {

for(int j=0;j<M;j++)

{

Simulate[i][j]=-1;

}

}

for(int q=0;q<M;q++)//初始化最久未使用数组 {

PageCount[q]=0;

}

10

操作系统课程设计

}

void OutPut()//输出

{

int i,j;

cout<<"页面访问序列:"<<endl;

for(j=0;j<MaxNum;j++)

{

cout<<PageOrder[j]<<" ";

}

cout<<endl;

cout<<"页面访问过程(只显示前10个):"<<endl;

for(i=0;i<10;i++)

{

for(j=0;j<M;j++)

{

if(Simulate[i][j]==-1)

cout<<" ";

else

cout<<Simulate[i][j]<<" ";

}

cout<<endl;

}

cout<<"缺页数= "<<LackNum<<endl;

cout<<"命中率= "<<PageRate<<endl;

cout<<"--------------------------------------------------------------"<<endl;

}

11

操作系统课程设计

void FIFO()//FIFO算法

{

int j,x=0,y=0;

LackNum=0,

Init();

for(j=0;j<M;j++)//将前五个页面请求直接放入内存中 {

for(int k=0;k<=j;k++)

{

if(j==k)

Simulate[j][k]=PageOrder[j];

else

Simulate[j][k]=Simulate[j-1][k];

}

//LackNum++;

}

for(x=M;x<MaxNum;x++)

{

for(int t=0;t<M;t++)//先将前一次页面访问过程赋值给新的页面访问过程

{

Simulate[x][t]=Simulate[x-1][t];

}

if(!IsExit(x))//根据新访问页面是否存在内存中来更新页面访问过程

{

LackNum++;

Simulate[x][y%M]=PageOrder[x];

12

操作系统课程设计

y++;

}

}

PageRate=1-((float)LackNum/(float)MaxNum);//算出命中率 OutPut();

}

void LRU()//LRU算法

{

int j,x=0,y=0;

LackNum=0,

Init();

for(j=0;j<M;j++)//将前五个页面请求直接放入内存中 {

for(int k=0;k<=j;k++)

{

PageCount[k]++;

if(j==k)

Simulate[j][k]=PageOrder[j];

else

Simulate[j][k]=Simulate[j-1][k];

}

LackNum++;

}

for(x=M;x<MaxNum;x++)

{

for(int t=0;t<M;t++)//先将前一次页面访问过程赋值给新的页面访问过程

{

13

操作系统课程设计

Simulate[x][t]=Simulate[x-1][t];

}

int p=IsExitLRU(x);

if(p==-1)//根据反回的p值来更新页面访问过程 {

int k;

k=Compare();

for(int w=0;w<M;w++)

{

if(w!=k)

PageCount[w]++;

else

PageCount[k]=1;

}

Simulate[x][k]=PageOrder[x];

LackNum++;

}

else

{

for(int w=0;w<M;w++)

{

if(w!=p)

PageCount[w]++;

else

PageCount[p]=1;

}

}

}

14

操作系统课程设计

PageRate=1-((float)LackNum/(float)MaxNum);//算出命中率 OutPut();

}

//最近最不常用调度算法(LFU)

void LFU(){}

void NUR(){}

void YourChoice(int choice)

{

switch(choice)

{

case 1:

cout<<"----------------------------------------------------------"<<endl;

cout<<"FIFO算法结果如下:"<<endl;

FIFO();

break;

case 2:

cout<<"----------------------------------------------------------"<<endl;

cout<<"LRU算法结果如下:"<<endl;

LRU();

break;

case 3:

cout<<"----------------------------------------------------------"<<endl;

cout<<"LFU算法结果如下:"<<endl;

//LFU();

break;

15

操作系统课程设计

case 4:

cout<<"----------------------------------------------------------"<<endl;

cout<<"NUR算法结果如下:"<<endl;

//NUR();

break;

case 5:

break;

default:

cout<<"重新选择算法:1--FIFO 2--LRU 3--LFU 4--NUR 5--退出 "<<endl;

cin>>choice;

YourChoice(choice);

}

}

void main()

{

int choice,i=1;

while(i)

{

cout<<"请选择算法:1--FIFO 2--LRU 3--LFU 4--NUR 5--退出 "<<endl;

cin>>choice;

if(choice==5)

{

i=0;

}

else

16

操作系统课程设计

{

YourChoice(choice);

}

} }

9. 实验体会

通过上面的截图可以发现,实验中指令是由随机函数产生的,然后根据产生的指令算出需要访问的页面.在本次实验中我写了四个页面置换算法—(先进先出)FIFO算法和(最久未使用)LRU算法, 最少访问页面算法 (LFR);最近最不经常使用算法 (NUR)。实验中的源程序是我根据书上的原理自己设计的.我从这次的实验中获得了很大的收益,让我对计算机操作系统中的页面置换算法有了进一步的了解,更加进一步地了解了计算机操作系统中的页面访问原理.

17

相关推荐