用DELPHI实现文件加密压缩.docx
- 文档编号:3598666
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:19
- 大小:22.29KB
用DELPHI实现文件加密压缩.docx
《用DELPHI实现文件加密压缩.docx》由会员分享,可在线阅读,更多相关《用DELPHI实现文件加密压缩.docx(19页珍藏版)》请在冰豆网上搜索。
用DELPHI实现文件加密压缩
述:
在这篇文件中,讲述对单个文件的数据加密、数据压缩、自解压的实现。
同样,也可以实现对多个文件或文件夹的压缩,只要稍加修改便可实现。
关键字:
加密压缩、Zlib、流、资源文件
引言:
在日常中,我们一定使用过WINZIP、WINRAR这样的出名的压缩软件,就是我们开发软件过程中不免要遇到数据加密、数据压缩的问题!
本文中就这一技术问题展开探讨,同时感谢各位网友的技巧,在我每次面对问题要解决的时候,是你们辛苦地摸索出来的技巧总是让我豁然开朗,问题迎刃而解。
本篇文章主要是运用DELPH的强大的流处理方面的技巧来实现的数据加密压缩,并用于实际的软件程序开发中,将我个人的心得、开发经验写出来与大家分享。
1、系统功能
1、数据压缩
使用DELPHI提供的两个流类 2、数据加密压缩 通过Delphi编程中"流"的应用实现数据加密,主要采用Tstream的两个派生类Tfilestream、Tmemorystream来完成的;其中数据压缩部分采用1的实现方法 3、双击压缩文件自动关联解压 通过更改注册表的实现扩展名与程序文件的关联,主要采用Tregistry;并且,API函数SHChangeNotify实现注册效果的立即呈现。 4、可生成自解压文件 自解压的文件实现数据压缩1与数据加密压缩2的自动解压;并且,通过资源文件的使用实现可执行的自解压文件与数据文件的合并,来完成数据的自解压实现。 2、系统实现 2.1、工作原理 2.2、关键技术的讲述 <一ZLIB 1、基类TCustomZlibStream: 是类TCompressionStream和TDecompressionStream类的基类,它主要有一个属性: OnProgress,在类进行压缩或解压缩的过程中会发生这个的事件。 格式: ProcedureOnProgress TObject;dynamic; 2、压缩类TCompressionStream: 除了继承了基类的OnProgress属性外,又增加了一个属性: CompressionRate,它的定义如下: PropertyCompressionRate: SinglereadGetCompressionRate; 通过这个属性,可以得到压缩比。 它的几个重要的方法定义如下: ConstructorTCompressionStream.Create TCompressionLevel;Dest: TStream; 其中: TcompressionLevel<压缩类型,它由如下几个定义: 1、clNone: 不进行数据压缩; 2、clFastest: 进行快速压缩,牺牲压缩效率; 3、clDefault: 进行正常压缩; 4、clMax: 进行最大化压缩,牺牲速度; Dest: 目的流,用于存放压缩过的数据。 FunctionTCompressionStream.Write Longint: Longint; 其中: Buffer: 需要压缩的数据; Count: 需要压缩的数据的字节数; 函数返回写入流的字节数。 注意: 压缩类TCompressionStream的数据只能是写入的,如果试图从其内部读取数据,将发生一个"Error"异常。 需要压缩的数据通过方法Write写入流中,在写入的过程中就被压缩,并保存在由构造函数提供的内存流 3、解压缩类TDecompressionStream: 和压缩类TcompressionStream相反,它的数据是只能读出的,如果试图往其内部写数据,将发生一个"Error"异常。 它的几个重要方法定义如下: 构造函数: ConstructorCreate TStream; 其中: Source是保存着压缩数据的流; FunctionRead Longint: Longint; 数据读出函数,Buffer: 存数据缓冲区;Count: 缓冲区的大小; 函数返回读出的字节数。 数据在读出的过程中,数据被解压缩,并触发OnProcess事件。 <二流 在Delphi中,所有流对象的基类为TStream类,其中定义了所有流的共同属性和方法。 TStream类中定义的属性如下: 1、Size: 此属性以字节返回流中数据大小。 2、Position: 此属性控制流中存取指针的位置。 Tstream中定义的虚方法有四个: 1、Read: 此方法实现将数据从流中读出,返回值为实际读出的字节数,它可以小于或等于指定的值。 2、Write: 此方法实现将数据写入流中,返回值为实际写入流中的字节数。 3、Seek: 此方法实现流中读取指针的移动,返回值为移动后指针的位置。 函数原形为: FunctionSeek Longint;Origint: Word: Longint;virtual;abstract; 参数Offset为偏移字节数,参数Origint指出Offset的实际意义,其可能的取值如下: soFromBeginning: Offset为指针距离数据开始的位置。 此时Offset必须大于或者等于零。 soFromCurrent: Offset为移动后指针与当前指针的相对位置。 soFromEnd: Offset为移动后指针距离数据结束的位置。 此时Offset必须小于或者等于零。 4、Setsize: 此方法实现改变数据的大小。 另外,TStream类中还定义了几个静态方法: 1、ReadBuffer: 此方法的作用是从流中当前位置读取数据,跟上面的Read相同。 注意: 当读取的数据字节数与需要读取的字节数不相同时,将产生EReadError异常。 2、WriteBuffer: 此方法的作用是在当前位置向流写入数据,跟上面的Write相同。 注意: 当写入的数据字节数与需要写入的字节数不相同时,将产生EWriteError异常。 3、CopyFrom: 此方法的作用是从其它流中拷贝数据流。 函数原形为: FunctionCopyFrom TStream;Count: Longint: Longint; 参数Source为提供数据的流,Count为拷贝的数据字节数。 当Count大于0时,CopyFrom从Source参数的当前位置拷贝Count个字节的数据;当Count等于0时,CopyFrom设置Source参数的Position属性为0,然后拷贝Source的所有数据; Tstream常见派生类: TFileStream<文件流的存取 TStringStream<处理内存中的字符串类型数据 TmemoryStream<对于工作的内存区域数据处理 TBlobStream TwinSocketStream ToleStream TresourceStream<资源文件流的处理 其中最常用的是TFileStream类。 使用TFileStream类来存取文件,首先要建立一个实例。 声明如下: constructorCreate string;Mode: Word; Filename为文件名<包括路径 Mode为打开文件的方式,它包括文件的打开模式和共享模式,其可能的取值和意义如下: 打开模式: fmCreate: 用指定的文件名建立文件,如果文件已经存在则打开它。 fmOpenRead: 以只读方式打开指定文件 fmOpenWrite: 以只写方式打开指定文件 fmOpenReadWrite: 以写写方式打开指定文件 共享模式: fmShareCompat: 共享模式与FCBs兼容 fmShareExclusive: 不允许别的程序以任何方式打开该文件 fmShareDenyWrite: 不允许别的程序以写方式打开该文件 fmShareDenyRead: 不允许别的程序以读方式打开该文件 fmShareDenyNone: 别的程序可以以任何方式打开该文件 <三资源文件 1、创建资源文件 首先创建一个.Rc的纯文本文件。 格式: 资源标识符关键字资源文件名 资源标识符: 程序中调用资源时的特殊标号; 关键字: 标识资源文件类型; Wave: 资源文件是声音文件; RCDATA: JPEG文件; AVI: AVI动画; ICON: 图标文件; BITMAP: 位图文件; CURSOR: 光标文件; EXEFILE: EXE文件 资源文件名: 资源文件的在磁盘上存储的文件全名 例如: myzjyexefilezjy.exe 2、编译资源文件 在DELPHI的安装目录的\Bin下,使用BRCC32.exe编译资源文件.RC。 当然,也可以将BRCC32单独拷贝到程序文档目录使用。 例如: Brcc32wnhoo_reg.Rc 3、资源文件引用 … implementation {$R*.dfm} {$Rwnhoo_reg.Res} … 4、调用资源文件 <1存取资源文件中的位图 Image.Picture.Bitmap.Handle: =LoadBitmap 注: 如果位图没有装载成功,程序仍旧执行,但是Image将不再显示图片。 你可以根据LoadBitmap函数的返回值判断是否装载成功,如果装载成功返回值是非0,如果装载失败返回值是0。 另外一个存取显示位图的方法如下 eName <2存取资源文件中的光标 Screen.Cursors[]是一个光标数组,使用光标文件我们可以将定制的光标加入到这个属性中。 因为默认的光标在数组中索引值是0,所以除非想取代默认光标,最好将定制的光标索引值设为1。 Screen.Cursors[1]: =LoadCursor Image.Cursor: =1; <3存取资源文件中的图标 将图标放在资源文件中,可以实现动态改变应用程序图标。 Application.Icon.Handle: =LoadIcon <4存取资源文件中的AVI Animate.ResName: ='MyAvi';//资源标识符号 Animate.Active: =True; <5存取资源文件中的JPEG 把jpeg单元加入到uses单元中。 var Fjpg: TJpegImage; FStream: TResourceStream; begin Fjpg: =TJpegImage.Create; //TresourceStream使用 FStream: =TResourceStream.Create FJpg.LoadFromStream Image.Picture.Bitmap.Assign <6存取资源文件中的Wave 把MMSystem加入uses单元中 PlaySound <四INI文件操作 <1INI文件的结构: ;这是关于INI文件的注释部分 [节点] 关键字=值 ... INI文件允许有多个节点,每个节点又允许有多个关键字,"="后面是该关键字的值<类型有三种: 字符串、整型数值和布尔值。 其中字符串存贮在INI文件中时没有引号,布尔真值用1表示,布尔假值用0表示。 注释以分号";"开头。 <2INI文件的操作 1、在Interface的Uses节增加IniFiles; 2、在Var变量定义部分增加一行: inifile: Tinifile;然后,就可以对变量myinifile进行创建、打开、读取、写入等操作了。 3、打开INI文件: inifile: =Tinifile.create<'tmp.ini'; 4、读取关键字的值: a: =inifile.Readstring<'节点','关键字',缺省值;//string类型 b: =inifile.Readinteger<'节点','关键字',缺省值;//integer类型 c: =inifile.Readbool<'节点','关键字',缺省值;//boolean类型 其中[缺省值]为该INI文件不存在该关键字时返回的缺省值。 5、写入INI文件: inifile.writestring<'节点','关键字',变量或字符串值; inifile.writeinteger<'节点','关键字',变量或整型值; inifile.writebool<'节点','关键字',变量或True或False; 当这个INI文件的节点不存在时,上面的语句还会自动创建该INI文件。 6、删除关键字: inifile.DeleteKey<'节点','关键字';//关键字删除 inifile.EraseSection<'节点';//节点删除 7、节点操作: inifile.readsection<'节点',TStrings变量;//可将指定小节中的所有关键字名读取至一个字符串列表变量中; inifile.readsections inifile.readsectionvalues<'节点',TStrings变量;//可将INI文件中指定小节的所有行<包括关键字、=、值读取至一个字符串列表变量中去。 8、释放: inifile.distory;或inifile.free; <五文件关联 uses registry,shlobj; //实现关联注册 procedureTmyzip.regzzz; var reg: TRegistry; begin reg: =TRegistry.Create; reg.RootKey: =HKEY_CLASSES_ROOT; reg.OpenKey<'.zzz',true; reg.WriteString<'','myzip'; reg.CloseKey; reg.OpenKey<'myzip\shell\open\command',true; //用于打开.zzz文件的可执行程序 reg.WriteString<'','"'+application.ExeName+'""%1"'; reg.CloseKey; reg.OpenKey<'myzip\DefaultIcon',true; //取当前可执行程序的图标为.zzz文件的图标 reg.WriteString<'',''+application.ExeName+',0'; reg.Free; //立即刷新 SHChangeNotify end; 2.3、加密压缩的实现 1、生成INI临时加密文件 用于加密的INI的临时文件格式: [FILE1]//节点,在软件中使用FILE1..N可以实现多文件加密 FILENAME=压缩文件名 PASSWORD=解压密码 FILESIZE=文件大小 FILEDATE=创建日期 ISJM=解压是否需要密码 如果是实现多文件、文件夹的信息存储,可以将密码关键字存在一个总的节点下。 本文中仅是实现对单个文件的加密,所以只要上述格式就可以了。 2、将数据文件与用于加密的INI文件的合并,这可以采用文件流的形式实现。 加密后文件结构图: 图<1 图<2 上面两种形式,可以根据实际采用。 本文采用图<1的结构。 3、对于加密后的数据,采用ZLIB技术实现压缩存储,生成新压缩形式的文件。 2.4、文件关联的实现见2.2<五 2.5、自解压的实现 1.建立一个专门用来自解压的可执行程序文件 2.将1中建立的文件,生成资源文件 3.将资源文件放到本文中这个压缩工具的程序中一起编译。 4.通过将资源文件与压缩文件的合并,生成自解压文件。 自解压文件结构图: 5.自解压实现: 通过将自身文件中的加密压缩数据的分解,然后对分解的加密压缩数据再一次解压并分解出真正的数据文件。 2.6系统程序设计 这是关于这个软件实现的核心部分全部代码,在这里详细讲述这个软件所有的技术细节。 //wnhoo_zzz.pas unitwnhoo_zzz; interface uses Windows,Forms,SysUtils,Classes,zlib,Registry,INIFILES,Dialogs,shlobj; type pass=string[20]; type Tmyzip=class private {privatedeclarationshere} protected {protecteddeclarationshere} public procedureregzzz; procedureys_file string;password: pass;isjm: boolean;ysbz: integer; functionjy_file string;password: pass='': boolean; procedurezjywj string; constructorCreate; destructorDestroy;override; {publicdeclarationshere} published {publisheddeclarationshere} end; implementation constructorTmyzip.Create; begin inheritedCreate;//初始化继承下来的部分 end; //##################################################### //原文件加密 procedurejm_File string;varTarget: TMemoryStream;password: pass;isjm: boolean; { vfile: 加密文件 target: 加密后输出目标流》》》 password: 密码 isjm: 是否加密 ------------------------------------------------------------- 加密后文件SIZE=原文件SIZE+[INI加密压缩信息文件]的SIZE+存储[INI加密压缩信息文件]的大小数据类型的SIZE --------------------------------------------------------------- } var tmpstream,inistream: TFileStream; FileSize: integer; inifile: TINIFILE; filename: string; begin //打开需要[加密压缩文件] tmpstream: =TFileStream.Create try //向[临时加密压缩文件流]尾部写入[原文件流] Target.Seek<0,soFromEnd; Target.CopyFrom //取得文件路径,生成[INI加密压缩信息文件] filename: =ExtractFilePath inifile: =TInifile.Create inifile.WriteString<'file1','filename',ExtractFileName inifile.WriteString<'file1','password',password; inifile.WriteInteger<'file1','filesize',Target.Size; inifile.WriteDateTime<'file1','fileDate',now<; inifile.WriteBool<'file1','isjm',isjm; inifile.Free; //读入[INI加密压缩信息文件流] inistream: =TFileStream.Create //继续在[临时加密压缩文件流]尾部加入[INI加密压缩信息文件] inistream.Position: =0; Target.Seek<0,sofromend; Target.CopyFrom //计算当前[INI加密压缩信息文件]的大小 FileSize: =inistream.Size; //继续在[临时加密文件尾部]加入[INI加密压缩信息文件]的SIZE信息Target.WriteBuffer finally inistream.Free; deletefile end; finally tmpstream.Free; end; end; //************************************************************** //流压缩 procedureys_stream TStream;ysbz: integer; { instream: 待压缩的已加密文件流 outStream压缩后输出文件流 ysbz: 压缩标准 } var ys: TCompressionStream; begin //流指针指向头部 inStream.Position: =0; //压缩标准的选择 caseysbzof 1: ys: =TCompressionStream.Create 2: ys: =TCompressionStream.Create 3: ys: =TCompressionStream.Create 4: ys: =TCompressionStream.Create else ys: =TCompressionStream.Create end
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DELPHI 实现 文件 加密 压缩