|
|
张小峰 |
|
超级版主
|
UID: 14
来自:
精华: 4
积分: 313
帖子: 285
注册: 2007-8-23 10:27:00
状态:
离线
威望: 8.00
金钱: 75.55 元
|
|
|
|
|
| 用DELPHI实现文件加密压缩 |
|
| 作者 : wnhoo | | 标题 : 用DELPHI实现文件加密压缩 | | 关键字: 加密压缩、Zlib、流、资源文件 | | 分类 : 开发经验 | | 密级 : 参赛 | | | (评分:★★★★ , 回复: 17, 阅读: 4837) 概述: 在这篇文件中,讲述对单个文件的数据加密、数据压缩、自解压的实现。同样,也可以实现对多个文件或文件夹的压缩,只要稍加修改便可实现。
关键字:加密压缩、Zlib、流、资源文件
引 言: 在日常中,我们一定使用过WINZIP、WINRAR这样的出名的压缩软件,就是我们开发软件过程中不免要遇到数据加密、数据压缩的问题!本文中就这一技术问题展开探讨,同时感谢各位网友的技巧,在我每次面对问题要解决的时候,是你们辛苦地摸索出来的技巧总是让我豁然开朗,问题迎刃而解。本篇文章主要是运用DELPH的强大的流处理方面的技巧来实现的数据加密压缩,并用于实际的软件程序开发中,将我个人的心得、开发经验写出来与大家分享。
1、 系统功能 1)、数据压缩 使用DELPHI提供的两个流类(TCompressionStream和TDecompressionStream)来完成数据的压缩和解压缩。 2)、数据加密压缩 通过Delphi编程中“流”的应用实现数据加密,主要采用Tstream的两个派生类Tfilestream、Tmemorystream 来完成的;其中数据压缩部分采用1)的实现方法 3)、双击压缩文件自动关联解压 通过更改注册表的实现扩展名与程序文件的关联,主要采用Tregistry;并且,API函数SHChangeNotify实现注册效果的立即呈现。 4)、可生成自解压文件 自解压的文件实现数据压缩1)与数据加密压缩2)的自动解压;并且,通过资源文件的使用实现可执行的自解压文件与数据文件的合并,来完成数据的自解压实现。
2、 系统实现 2.1、工作原理
2.2、关键技术的讲述 (一)ZLIB 1)、基类 TCustomZlibStream:是类TCompressionStream和TDecompressionStream 类的基类,它主要有一个属性: OnProgress,在类进行压缩或解压缩的过程中会发生这个的事件 。 格式:Procedure OnProgress (Sender: Tobject); dynamic; 2)、压缩类TCompressionStream:除了继承了基类的OnProgress 属性外,又增加了一个属性:CompressionRate,它的定义如下: Property CompressionRate: Single read GetCompressionRate; 通过这个属性,可以得到压缩比。 它的几个重要的方法定义如下: Constructor TCompressionStream.Create (CompressionLevel: TCompressionLevel; Dest: Tstream); 其中:TcompressionLevel(压缩类型),它由如下几个定义: 1)、 clNone :不进行数据压缩; 2)、 clFastest:进行快速压缩,牺牲压缩效率; 3)、 clDefault:进行正常压缩; 4)、 clMax: 进行最大化压缩,牺牲速度; Dest:目的流,用于存放压缩过的数据。 Function TCompressionStream.Write (const Buffer; Count: Longint): Longint; 其中:Buffer:需要压缩的数据; Count: 需要压缩的数据的字节数; 函数返回写入流的字节数。 注意:压缩类TCompressionStream的数据只能是写入的,如果试图从其内部读取数据,将发生一个"Error "异常。需要压缩的数据通过方法 Write写入流中,在写入的过程中就被压缩,并保存在由构造函数提供的内存流(TmemoryStream)中,同时触发 OnProcess 事件。 3)、 解压缩类 TDecompressionStream :和压缩类TcompressionStream相反,它的数据是只能读出的,如果试图往其内部写数据,将发生一个"Error "异常。 它的几个重要方法定义如下: 构造函数:Constructor Create(Source: Tstream); 其中:Source 是保存着压缩数据的流; Function Read(var Buffer; Count: Longint): Longint; 数据读出函数,Buffer: 存数据缓冲区;Count: 缓冲区的大小; 函数返回读出的字节数。数据在读出的过程中,数据被解压缩,并触发 OnProcess 事件。
(二)流 在Delphi中,所有流对象的基类为Tstream类,其中定义了所有流的共同属性和方法。 Tstream类中定义的属性如下: 1)、Size:此属性以字节返回流中数据大小。 2)、Position:此属性控制流中存取指针的位置。
Tstream中定义的虚方法有四个: 1)、Read:此方法实现将数据从流中读出,返回值为实际读出的字节数,它可以小于或等于指定的值。 2)、Write:此方法实现将数据写入流中,返回值为实际写入流中的字节数。 3)、Seek:此方法实现流中读取指针的移动,返回值为移动后指针的位置。 函数原形为:Function Seek(Offset: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:此方法的作用是从其它流中拷贝数据流。 函数原形为:Function CopyFrom(Source:Tstream;Count:Longint):Longint; 参数Source为提供数据的流,Count为拷贝的数据字节数。当Count大于0时,CopyFrom从Source参数的当前位置拷贝Count个字节的数据;当Count等于0时,CopyFrom设置Source参数的Position属性为0,然后拷贝Source的所有数据;
Tstream常见派生类: TFileStream (文件流的存取) TStringStream (处理内存中的字符串类型数据) TmemoryStream (对于工作的内存区域数据处理) TBlobStream (BLOB类型字段的数据处理) TwinSocketStream (socket的读写处理) ToleStream (COM接口的数据处理) TresourceStream (资源文件流的处理) 其中最常用的是TFileStream类。使用TFileStream类来存取文件,首先要建立一个实例。声明如下: constructor Create(const Filename: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文件 资源文件名:资源文件的在磁盘上存储的文件全名
例如: myzjy exefile zjy.exe
2)、编译资源文件 在DELPHI的安装目录的\Bin下,使用BRCC32.exe编译资源文件.RC。当然,也可以将BRCC32单独拷贝到程序文档目录使用。 例如: Brcc32 wnhoo_reg.Rc
3)、资源文件引用 … implementation
{$R *.dfm} {$R wnhoo_reg.Res} … 4)、调用资源文件 (1)存取资源文件中的位图(Bitmap) Image.Picture.Bitmap.Handle :=LoadBitmap(hInstance,'资源标识符'); 注:如果位图没有装载成功,程序仍旧执行,但是Image将不再显示图片。你可以根据LoadBitmap函数的返回值判断是否装载成功,如果装载成功返回值是非0,如果装载失败返回值是0。
另外一个存取显示位图的方法如下 Image.Picture.Bitmap.LoadFromResourceName(hInstance,'资源标识符');
(2)存取资源文件中的光标 Screen.Cursors[]是一个光标数组,使用光标文件我们可以将定制的光标加入到这个属性中。因为默认的光标在数组中索引值是0,所以除非想取代默认光标,最好将定制的光标索引值设为1。 Screen.Cursors[1] :=LoadCursor(hInstance,'资源标识符'); Image.Cursor :=1;
(3)存取资源文件中的图标 将图标放在资源文件中,可以实现动态改变应用程序图标。 Application.Icon.Handle := LoadIcon(hInstance,'资源标识符');
(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 (Hinstance,'资源标识符',资源类型) ; FJpg.LoadFromStream (Fstream) ; Image.Picture.Bitmap.Assign (FJpg);
(6)存取资源文件中的Wave 把MMSystem加入uses单元中 PlaySound(pchar('mywav'),Hinstance,Snd_Async or Snd_Memory or snd_Resource) ;
|
|
|
|
|