首页> 中国专利> .net文件中引用类型的压缩方法和装置

.net文件中引用类型的压缩方法和装置

摘要

本发明公开了一种.net文件中引用类型的压缩方法和装置,根据本发明的.net文件中引用类型的压缩方法包括:获取.net文件中使用的引用类型的名称,并进行压缩,得到压缩后的引用类型的名称;统计所述引用类型的方法计数和字段计数;对所述压缩后的引用类型的名称、所述方法计数和所述字段计数进行组合,得到所述引用类型的压缩结果。通过对引用类型进行压缩,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如:智能卡)上存储并运行,进而增强了小容量存储介质(例如:智能卡)的功能。

著录项

  • 公开/公告号CN101794221A

    专利类型发明专利

  • 公开/公告日2010-08-04

    原文格式PDF

  • 申请/专利权人 北京飞天诚信科技有限公司;

    申请/专利号CN200910244165.2

  • 发明设计人 陆舟;于华章;

    申请日2009-12-30

  • 分类号G06F9/44;G06F17/30;

  • 代理机构北京康信知识产权代理有限责任公司;

  • 代理人余刚

  • 地址 100191 北京市海淀区学院路40号研7A楼5层

  • 入库时间 2023-12-18 00:31:18

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2012-08-08

    授权

    授权

  • 2010-09-22

    实质审查的生效 IPC(主分类):G06F9/44 申请日:20091230

    实质审查的生效

  • 2010-08-04

    公开

    公开

说明书

技术领域

本发明涉及计算机应用领域,具体而言,涉及一种.net文件中引用类型的压缩方法和装置。

背景技术

.Net是微软的新一代技术平台,是全新的基于互联网的跨语言软件开发平台,顺应了当今软件工业分布式计算、面向组件、企业级应用、软件服务化和以Web为中心等大趋势。.Net并非开发语言,但是在.Net开发平台上可以支持多种开发语言,如C#语言、C++、Visual Basic、Jscript等。

智能卡是一种大小和普通名片相仿的塑料卡片,内含一块直径1cm左右的硅芯片,具有存储信息和进行复杂运算的功能。它被广泛地应用于电话卡、金融卡、身份识别卡以及移动电话、付费电视等领域。其中,智能卡的芯片上,集成了微处理器、存储器以及输入/输出单元等,使得智能卡被认为是世界上最小的电子计算机。并且在智能卡上,拥有一整套性能较强的安全保密控制机制,安全控制程序被固化在只读存储器中,因而具有无法复制密码等可靠的安全保证。它较之普通磁卡,还具有信息存储容量大,可利用微处理器来增加卡片功能等优点。

.Net卡是一种含有可以运行.Net程序的.Net卡虚拟机的微处理器智能卡。所谓虚拟机,是指可以把它想象成一台用软件来模拟的机器,在这台机器里有处理器、内存、寄存器等各种硬件,模拟运行各种指令,在这台机器上运行的软件对运行环境没有特殊要求,所以虚拟机对在它上运行的程序来说是透明的。例如,x86虚拟机模拟的是x86指令程序的运行环境,c51虚拟机模拟的是c51指令程序的运行环境。

.net程序包括命名空间、引用类型、定义类型、定义方法、引用方法、IL(Intermediate Language,中间语言)代码等,其中引用类型是由类型的实际值引用(类似于指针)表示的数据类型。

但是目前的智能卡由于体积和存储芯片的限制,其存储空间仍然有限,随着软件的发展,部分功能大的程序占用存储空间较大,对于很多的.net程序并不能进行存储和运行。

综上所述,相关技术中的.net程序不能很好地在小容量的存储介质(例如:智能卡)上存储和运行,且针对该问题目前尚未提出有效的解决方案。

发明内容

针对.net程序不能很好地在小容量的存储介质(例如:智能卡)上存储和运行而提出本发明,为此,本发明的主要目的在于提供一种.net文件中引用类型的压缩方法和装置,以解决上述问题至少之一。

为了实现上述目的,根据本发明的一个方面,提供了一种.net文件中引用类型的压缩方法。

根据本发明的.net文件中引用类型的压缩方法包括:

获取.net文件中使用的引用类型的名称,并进行压缩,得到压缩后的引用类型的名称;

统计所述引用类型的方法计数和字段计数;

按照预先确定的格式对所述压缩后的引用类型的名称、所述方法计数和所述字段计数进行组合,得到所述引用类型的压缩结果。

为了实现上述目的,根据本发明的另一方面,提供了一种.net文件中引用类型的压缩装置,所述装置包括:

引用类型名称获取模块,用于获取.net文件中使用的引用类型的名称;

压缩模块,用于对所述引用类型名称获取模块获取的引用类型的名称进行压缩,得到压缩后的引用类型的名称;

统计模块,用于统计所述引用类型名称获取模块获取的引用类型的方法计数和字段计数;

组合模块,用于按照预先确定的格式对所述压缩模块压缩后的引用类型的名称、所述统计模块统计出的方法计数和字段计数进行组合,得到所述引用类型的压缩结果。

本发明采用对获取到的引用类型的名称进行压缩,并将压缩后的引用类型的名称与统计出的方法计数和字段计数进行组合,得到压缩后的引用类型,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如:智能卡)上存储并运行,进而增强了小容量存储介质(例如:智能卡)的功能。

附图说明

此处所说明的附图用来提供对本发明的进一步理解,构成本申请的一部分,本发明的示意性实施例及其说明用于解释本发明,并不构成对本发明的不当限定。在附图中:

图1是本发明实施例1提供的.net文件中引用类型的压缩装置的结构框图;

图2是本发明实施例1提供的引用类型名称获取模块的具体结构框图;

图3是本发明实施例2提供的.net文件中引用类型的压缩方法的流程图;

图4是本发明实施例3提供的.net文件中引用类型的压缩方法的流程图;

图5是本发明实施例3提供的.net文件的结构示意图;

图6是本发明实施例3提供的统计引用类型的方法计数和字段计数的方法流程图。

具体实施方式

下文中将参考附图并结合实施例来详细说明本发明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互组合。

下面结合附图对技术方案的实施作进一步的详细描述:

实施例1

本实施例提供了一种.net文件中引用类型的压缩装置,如图1所示,该装置包括:引用类型名称获取模块102、压缩模块104、统计模块106和组合模块108,各个模块的功能如下:

引用类型名称获取模块102,用于获取.net文件中使用的引用类型的名称;

压缩模块104,用于对引用类型名称获取模块102获取的引用类型的名称进行压缩,得到压缩后的引用类型的名称;

统计模块106,用于统计引用类型名称获取模块102获取的引用类型的方法计数和字段计数;

组合模块108,用于按照预先确定的格式对压缩模块104压缩后的引用类型的名称、统计模块106统计出的方法计数和字段计数进行组合,得到引用类型的压缩结果。

其中,引用类型名称获取模块102可以采用多种方式获取引用类型的名称,本实施例以图2所示为例进行说明,如图2所示,为本实施例提供的引用类型名称获取模块的具体结构框图,引用类型名称获取模块102包括:

第一元数据表获取单元1022,用于获取.net文件中第一元数据表;在.net文件中包含有多个表,本实施例中将元数据表TypeRef(引用类型或接口表)作为第一元数据表,该表中记录了.net文件中使用的引用类型的名称和该引用类型所属的命名空间。

地址信息读取单元1024,用于从第一元数据表获取单元1022获取的第一元数据表中读取该.net文件中使用的引用类型的名称的地址信息;

引用类型名称读取单元1026,用于根据地址信息读取单元1024读取的地址信息读取引用类型的名称。

优选的,压缩模块104进行压缩时采用的算法可以是散列算法,具体而言,可以为MD5、SHA-1或SHA-2等。

统计模块106在统计方法计数和字段计数时,可以根据第二元数据表中记录的信息进行统计,其中,第二元数据表为.net文件中的元数据表MemberRef,该表中的每行数据记录了引用类型信息和特征标识值,根据引用类型信息中的数据可以确定当前行数据指向第一元数据表TypeRef中第几行记录的引用类型,进而确定该当前行数据指向的引用类型的名称;特征标识值中的数据用以指明该当前行数据记录的是方法还是字段,根据特征标识值中的数据则可以统计出每个引用类型的名称对应的方法计数和字段计数。

优选的,组合模块108中的预先确定的格式为固定长度的字节,该固定长度的字节包括三部分,其中,第一部分为压缩后的引用类型的名称,第二部分为方法计数,第三部分为字段计数。这三部分可以任意组合。

在引用类型的压缩结果中包含方法计数和字段计数的目的是:当.net文件的其他部分也进行了对应的压缩时,可以根据该方法计数查找到对应的方法,根据字段计数查找到对应的字段,使压缩后的引用类型能够正常使用。

本实施例中的压缩模块104采用对引用类型名称获取模块102获取到的引用类型的名称进行压缩,组合模块108通过对压缩模块104压缩后的引用类型的名称和统计模块106统计出的方法计数、字段计数进行组合,得到压缩后的引用类型,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如:智能卡)上存储并运行,进而增强了小容量存储介质(例如:智能卡)的功能。

实施例2

本实施例提供了一种.net文件中引用类型的压缩方法,该方法以在实施例1提供的压缩装置中运行为例进行说明,如图3所示,该方法包括:

步骤S202:引用类型名称获取模块102获取.net文件中使用的引用类型的名称;

步骤S204:压缩模块104对引用类型名称获取模块102获取的引用类型的名称进行压缩,得到压缩后的引用类型的名称;

步骤S206:统计模块106统计引用类型名称获取模块102获取的引用类型的方法计数和字段计数;

步骤S208:组合模块108按照预先确定的格式对压缩模块104压缩后的引用类型的名称、统计模块106统计出的方法计数和字段计数进行组合,得到引用类型的压缩结果。

优选的,步骤S202具体包括:引用类型名称获取模块102获取.net文件中第一元数据表;从第一元数据表中读取该.net文件中使用的引用类型的名称的地址信息;根据该地址信息读取上述引用类型的名称。

优选的,步骤S202中还可以包括根据获取的引用类型的名称生成引用类型名称字符串的步骤,该引用类型名称字符串具体可以采用以下两种方式中的任一种实现:

1)压缩模块104将上述获取的引用类型的名称转换成预定的编码格式,例如ASCII编码,生成引用类型名称字符串。

2)压缩模块104先获取上述引用类型所属的命名空间名称;将该命名空间名称与上述引用类型的名称组合,生成引用类型名称字符串。

压缩模块104对上述引用类型的名称进行压缩的步骤包括:对上述引用类型的名称(或者生成的引用类型名称字符串)进行散列运算得到散列值;取所述散列值中预定的字节作为压缩后的引用类型的名称。其中,散列运算采用的算法为:MD5、SHA-1或SHA-2等。

优选的,统计模块106统计方法计数和字段计数的步骤具体包括:获取第二元数据表;对该第二元数据表的每一行执行下述操作:

读取该第二元数据表中当前行数据所指向的引用类型;

当上述当前行数据指向的引用类型的名称与引用类型名称获取模块102获取的引用类型的名称一致时,根据上述当前行数据的特征标识值判断该当前行数据记录的是否为方法,如果是,将上述引用类型的方法计数加1;否则,将上述引用类型的字段计数加1。

优选的,组合模块108中提到的预先确定的格式为固定长度的字节,该固定长度的字节包括三部分,其中,第一部分为压缩后的引用类型的名称,第二部分为方法计数,第三部分为字段计数。

其中,上述第一元数据表和第二元数据表可以具体为实施例1中的元数据表,这里不再赘述。

本实施例提供的方法是以在实施例1提供的压缩装置中实现为例进行的说明。采用对获取到的引用类型的名称进行压缩,组合压缩后的引用类型的名称和统计出的方法计数、字段计数,得到压缩后的引用类型,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如:智能卡)上存储并运行,进而增强了小容量存储介质(例如:智能卡)的功能。

实施例3

本实施例提供了一种.net文件中引用类型的压缩方法,该方法中将经过.net平台编译后的未被压缩的文件称为.net文件。

如图4所示,为本实施例提供的.net文件中引用类型的压缩方法流程图,包括步骤S302至步骤S310,具体如下:

步骤S302:获取.net文件中的第一元数据表,本实施例中的第一元数据表具体为元数据表TypeRef;

在.net文件中包含有多个表,其中元数据表TypeRef(引用类型或接口表)中记录了.net文件中使用的引用类型的名称和该引用类型所属的命名空间的信息;

元数据表为PE(Portable Excutable,可移植可执行)文件的一部分,本实施例以将下面的代码编译后得到的.net文件为例进行说明:

namespace MyCompany.MyOnCardApp

{

    public class MyService:MarshalByRefObject

    {

         static Version ver=new Version(1,1,1,1);

         static Int32 callCount=0;

         static ClassB classb=new ClassB();

         String strResult=Boolean.FalseString;

          public String My SampleMethod()

          {

                String strHello=″Hello World!″;

                return strHello+callCount.ToString();

          }

     }

public class ClassB{}

public struct StructB{}

}

对上述代码使用.net平台编译后得到helloworld.exe文件,并以二进制的形式存储在硬盘上,该二进制文件为.net文件,如图5所示,为本实施例提供的.net文件的结构示意图,该文件包括Dos头、PE特征以及元数据(MetaData),元数据中包括元数据头(MetaDataHeader)、元数据表(tables)等。

下面对获取元数据表TypeRef的过程进行说明:

a.定位.net文件的Dos头,本实施例得到的Dos头为0x5a4d;

b.从dos头后跳过第一约定个字节,读出PE特征的偏移地址,得到PE特征的偏移地址0x00000080;

在本实施例中,第一约定个字节为0x003a个字节;

c.根据PE特征偏移地址0x00000080定位PE特征,定位得到PE特征0x4550;

d.在PE特征向后偏移第二约定个字节后读取四个字节,在本实施例中,以32位机为例进行说明,第二约定个字节为从PE特征向后偏移0x0074字节后,读出4个字节的数据为0x00000010,此值说明该二进制文件中存在0x10个目录且包含.net数据;

其中,.net文件的元数据头相对虚拟地址写在上述第0x0F个目录中,在64位机中第二约定个字节为0x0084个字节;

e.从上述数据0x00000010,向后偏移第三约定个字节后读取八个字节数据,在本实施例中,优选地,第三约定个字节为112个字节,在此八个字节数据中,前四个字节为0x00002008,为.net数据头的相对虚拟地址,后四个字节为0x00000048,为.net数据头的长度;

f.根据.net数据头的相对虚拟地址得到线性地址0x00000208,并读取.net数据头得到如下数据:

48000000020005008C210000A0090000

090000000500000600000000000000005

020000080000000000000000000000000

000000000000000000000000000000000

0000000000000

需要说明的是,上述数据采用小端的存储方式,例如,上述数据前4个字节0x48000000为该数据的长度,转换成大端的存储方式为0x0000048;

在本实施例中,线性地址为.net数据在.net文件中的地址,相对虚拟地址为相对于PE载入点的内存偏移,线性地址和相对虚拟地址的转换关系为:线性地址=相对虚拟地址-节相对虚拟地址+节的文件偏移,在本实施例中,读取.net文件中.net数据目录的节的相对虚拟地址为0x00002000,节的文件偏移为0x00000200,则线性地址=0x00002008-0x00002000+0x00000200=0x00000208;

g.由.net数据头向后偏移第四约定个字节后读取八个字节数据,在本实施例中第四约定个字节为从.net数据头向后偏移8个字节后,读取共8个字节,在这8个字节中,前四个字节为0x0000218c,为元数据头(MetaData Header)的相对虚拟地址,后四个字节为0x000009a0,为元数据的长度;

h.将元数据头的相对虚拟地址0x0000218c转换得到线性地址0x0000038c,根据线性地址和元数据长度,得到元数据内容;

i.由元数据头向后读取,当读取到标志“#~”时,读取标志“#~”前的八个字节,其中前四个字节为“#~”的地址,通过该地址得到“#~”流,在“#~”流中第五约定个字节开始读取开始读取长度为8个字节的数据,即0x0000000920021c57,其二进制形式为100100100000000000100001110001010111;

在本实施例中,第五约定个字节为“#~”流中起始位开始算起第9个字节;

j.根据步骤i中得到的二进制数据,从低位开始读取,例如,第1位代表元数据表Module是否存在,如果是1则证明存在元数据表Module,如果是0证明不存在,在本实施例中,存在元数据表Module,并且第2位为1表示元数据表TypeRef存在;其中,在步骤i中所得到的数据中,从低位开始,每一位代表.net文件中是否存在对应的表;

k.在数据0x0000000920021c57后偏移第六约定个字节后读取元数据表TypeRef的数据行数,在本实施例中为向后偏移12个字节后读取4个字节,得到数据0x0000001e,判断得出元数据表TypeRef中存在30个数据行;其中,在元数据中,数据0x0000000920021c57向后偏移8个字节后的数据中以每4个字节为一个单位依次存储了在.net文件中存在的元数据表的数据行数,在表示数据行数的数据后,依次存储了每个元数据表的具体内容,为元数据表区域;

l.根据约定的方法读取元数据表TypeRef的具体内容。其中,约定的方法如下,以本实施例中的.net文件为例进行说明,在步骤j中判断得出元数据表Module存在,并读取其数据行数为1,元数据表Module的数据行每行数据为10个字节,因此在元数据表区域中,向后偏移10个字节,第11个字节开始为元数据表TypeRef的内容,元数据表TypeRef的数据行为30行,每行数据为6个字节,因此元数据表TypeRef的数据长度为30*6=180个字节;

元数据表TypeRef的部分数据如下:

0600 6100 5A00

0600 7400 5A00

0600 7B00 5A00

0600 8500 5A00

0600 EF00 DD00

0600 0801 DD00

0600 2101 DD00

0600 3C01 DD00

上述数据为本实施例所提供的.net文件中元数据表TypeRef中的前8行数据,在本实施例中元数据表TypeRef共30行数据,剩余的数据处理方法相同,不再一一列举。

在上述数据的每一行中,由高位到低位,前两个字节为类型解析作用域的编码标识,第3、4个字节为该引用类型的名称在“#Strings”流中的偏移量,后两个字节为该引用类型所属的命名空间名称在“#Strings”流中的偏移量,为便于说明,参见表1所示:

表1

  类型解析作用域编码标识  (Resolution Scop) 类型名称(Type Name)  命名空间  (Namespace)  0060 0061  005a  0060 0074  005a  0060 007b  005a  0060 0085  005a  0060 00ef  00dd  0060 0801  00dd  0060 0121  00dd  0060 013c  00dd

需要说明的是,表中的数据使用大端的表示方法,例如第一个数据行的数据为0060,0061,005a,对应的小端表示方法为0600 61005a00;

在使用本实施例提供的压缩方法时,初始化设定所有引用类型的方法计数为0,所有引用类型的字段计数为0,上述引用类型的方法计数为在.net文件中该引用类型包括的方法的个数,引用类型的字段计数为该引用类型包括的字段的个数;

步骤S304:读取.net文件中引用类型的名称,并将该引用类型的名称转换为引用类型名称字符串;

在步骤S302中获取了引用类型的名称相对于“#Strings”流的偏移量,本实施例以元数据表TypeRef中第一个引用类型,即相对偏移量为0x0061的引用类型为例,说明获取引用类型的名称方法如下:

在步骤S302中的步骤h中获得元数据头的地址0x0000038c后,从元数据头开始向后读取,当发现标记“#Strings””后,读取“#Strings”的前8个字节,得到数据0x5C0300003C040000;

数据0x5C0300003C040000的高4个字节为“#Strings”流相对于元数据头的偏移,低4个字节为“#Strings”流的长度,其中,高4个字节转换成大端的表示方式为0x0000035c,低4个字节转换成大端的表示方式为0x0000043c;

根据元数据头的地址0x0000038c向后偏移0x0000035c得到“#Strings”流的数据区域,根据元数据表TypeRef中第一个引用类型的偏移量,由“#Strings”流的头向后偏移0x0061,并向后读取直到00结束,得到第一个引用类型的名称为0x4D61727368616C42795265664F626A656374;

通过ASC II码对第一个引用类型的名称进行转换得到引用类型名称字符串MarshalByRefObject,其他引用类型的名称读取与转换方法与第一个引用类型的名称相同,不再赘述;

其中,引用类型名称字符串还可以通过下述方法获取:获取引用类型的名称,并获取该引用类型所属的命名空间名称,将命名空间名称使用连接符“.”与引用类型的名称连接得到引用类型名称字符串,例如第一个引用类型所属的命名空间为System,按上述方法可得到第一个引用类型的名称转换后的引用类型名称字符串:System.MarshalByRefObject;

步骤S306:对引用类型名称字符串进行散列运算,并取预定的字节作为压缩后的引用类型的名称;

其中,进行散列运算的算法可以为MD5、SHA-1、SHA-2等,本实施例中,优选地采用MD5算法进行说明,对步骤S304中得到的引用类型名称字符串“MarshalByRefObject”进行MD5运算得到一个120位的MD5值“3064AB63C4B4DC57770E9BDF25B7547D”;

在本实施例中,优选地取上述MD5值前两个字节作为压缩后的引用类型的名称,即“3064”;

需要说明的是,在本实施例中,可以按照步骤S302-S306的顺序,依次读取一个引用类型的名称并进行压缩得到压缩结果,也可以先获得.net文件中所有的引用类型的名称,然后对得多引用类型的名称逐一进行压缩得到压缩结果,并将得到的压缩结果进行缓存;

步骤S308:统计上述得到的引用类型的方法计数和字段计数;

参见图6,为本实施例提供的统计引用类型的方法计数和字段计数的方法流程图,引用类型的方法计数和字段计数统计方法如下:

步骤S3081:获取第二元数据表,本实施例中的第二元数据表具体为元数据表MemberRef;

在本实施例中,获取元数据表MemberRef的过程包括:

由步骤S302中获取元数据表TypeRef的步骤i中获得的二进制数据100100100000000000100001110001010111可知,由低位开始读取,第11位为1表示元数据表MemberRef存在,第11位前共有5个1,判断得出元数据表MemberRef前存在其他5个元数据表;

由步骤k得知,读取得到的元数据表MemberRef中存在23个数据行,并且元数据表MemberRef前的五个表中共存在50个数据行;其中,元数据表Module包括数据行为1行,元数据表TypeRef包括数据行为30行,元数据表TypeDef包括数据行为6行,元数据表Field包括数据行为7行,元数据表Method包括数据行为6行;

根据步骤S302中的步骤1中约定的方法得知,元数据表Module的数据行中每行为10个字节,元数据表TypeRef的数据行中每行为6个字节,元数据表TypeDef的数据行中每行为14个字节,元数据表Field的数据行中每行为6个字节,元数据表Method的数据行中每行为14个字节;

因此元数据表MemberRef在元数据表区域的偏移地址为1*10+30*6+6*14+7*6+6*14=400,从元数据表区域开始偏移400个字节后得到元数据表MemberRef的内容,元数据表MemberRef的数据行为每行6个字节,计算得到元数据表MemberRef的长度为23*6=138个字节,元数据表MemberRef的部分数据如下:

2900 C000 4300

3100 C000 4300

3900 C000 4800

4100 C000 4300

4900 C000 4300

5100 C000 4300

5900 C000 4300

6100 C000 4300

上述数据为本实施例所提供的.net文件的元数据表MemberRef中的前8行中的数据,其他数据处理方法相同,这里不再一一列举。

在元数据表MemberRef中储存有引用类型的方法和字段信息,上述数据的每一行记录一个方法或字段的引用特征,即特征标识值(signature)。其中,每行数据的高2个字节表示该字段或方法指向的引用类型,中间2个字节为该字段或方法的名称,低2个字节表示该方法或字段的特征标识值相对于“#Blob”流的偏移量,特征标识值signature记录了该数据行所表示的为方法还是字段,以及返回值等信息。

为了便于说明,参见表2,表2为上述8行数据的列表形式:

表2

 指向的引用类型Class  名称Name 特征标识值signature 0029  00c0 0043 0031  00c0 0043 0039  00c0 0043 0041  00c0 0043 0049  00c0 0043 0051  00c0 0043 0059  00c0 0043 0061  00c0 0043

步骤S3082:读取元数据表MemberRef中每个方法或字段指向的引用类型;

如表2所示,高2个字节记录的为该行方法或字段指向的引用类型,下面以元数据表MemberRef中第一行数据进行说明,Class为0x0029,将0x0029转换成二进制101001,向右移3位得到101,转换成十进制为5,则元数据表MemberRef中第一行的字段或方法指向元数据表TypeRef中第5行所记录的引用类型,通过步骤S302和步骤S304所述的方法可得到元数据表TypeRef中第5行所记录的引用类型的名称为AssemblvKevNameAttribute;

步骤S3083:依次获取元数据表MemberRef中每个方法或字段的特征标识值signature;

如表2所示,在元数据表MemberRef中每一行的低2字节为该方法或字段的特征标识值signature相对于“#Blob”流的偏移;获取元数据表MemberRef中每个方法或字段的signature的方法如下:

定位“#Blob”流的位置,即在步骤S302中的步骤h中获得元数据头的地址0x0000038c后,从元数据头开始向后读取,当发现标记“#Blob”后,读取“#Blob”前的8个字节,得到数据0xE4070000BC010000,其中高4个字节为“#Blob”流相对于元数据头的偏移,低4个字节为“#Blob”流的长度,高4个字节转换成大端的表示方式为0x000007e4,低4个字节转换成大端的表示方式为0x000001bc;压缩程序根据元数据头的地址0x0000038c,向后偏移0x000007e4得到“#Strings”流的数据区域;

本实施例以读取元数据表MemberRef中第一行数据行为例进行说明,第一行特征标识值signature偏移为0x0043,在“#Blob”流中偏移0x0043获得第一行数据的特征标识值signature为0x2001010e;

步骤S3084:根据读出的特征标识值signature判断该当前行数据记录的是方法还是字段,如果是方法,执行步骤S3085,如果是字段,执行步骤S3086;

本实施例以读取元数据表MemberRef中第一行数据行读出的特征标识值signature为例进行说明,根据读出的特征标识值signature判断是方法还是字段的具体过程如下:

第一行数据行读出的特征标识值signature为0x2001010e,本实施例的判断标准为当特征标识值signature的后4位为0x060e时,该当前行数据记录的为字段,否则,该行数据记录的为方法;由此可知,在本实施例中,元数据表第一行数据记录的为方法,即引用类型AssemblvKevNameAttribute引用了元数据表MemberRef中第一行所记录的方法;

步骤S3085:将元数据表MemberRef中该当前行数据所指向的引用类型的方法计数加1,然后返回步骤S3083;

步骤S3086:将元数据表MemberRef中该当前行数据所指向的引用类型的字段计数加1,然后返回步骤S3083;

通过步骤S3081-S3086中提供的方法,将元数据表MemberRef全部读取完成后,得到.net文件中所有引用类型的方法计数和字段计数;

需要说明的是,在本实施例中,步骤S302-S306与步骤S308的顺序可以互换执行,即先执行步骤S308,再执行步骤S302-S306,也可得到本实施例相同的效果;

步骤S310:按照预先确定的格式对压缩后的引用类型的名称、该引用类型的方法计数和字段计数进行组合,得到引用类型的压缩结果;

在本实施例中,预先确定的格式可以为表3所示格式,即该格式为一段固定长度的字节,该固定长度可以根据需要设定,这段字节中包括三个部分,第一部分为压缩后的引用类型的名称,第二部分为该引用类型的方法计数,第三部分为该引用类型的字段计数。

表3

  压缩后的引用类型的名称  方法计数  字段计数

按照表3所示结构将步骤S306中得到的压缩后的引用类型的名称和与其对应的方法计数和字段计数进行组合,得到压缩后的引用类型,当该引用类型的方法计数或字段计数为0时,使用0x00进行填充,例如对引用类型MarshalByRefObject的压缩结果为:0x30640100。

表3所示的压缩结构仅为最优的结构,压缩结构还可以做相应的变换,例如将上述压缩结构中方法计数、字段计数置于压缩后的引用类型的名称后,或将方法计数、字段计数的值进行同等编码变换等;

下面给出一个.net文件中引用类型的压缩结果:

(0)8E3B 0100 0000

    //System.Runtime.CompilerServices.RuntimeHelpers

(1)DB8C 0100 0000

    //.HelloWorld.exe.3805F8269D52A5B2.

(2)81CE 0000 0000//System.Void

(3)2711 0100 0000//System.String

(4)2722 0000 0100//System.Boolean

(5)3064 0100 0000//System.MarshalByRefObject

(6)34B6 0100 0000//System.Version

(7)C061 0100 0000//System.Int32

(8)A245 0000 0000//System.Byte

(9)4410 0000 0000//System.Array

(10)4970 0100 0000//System.Object

(11)ED88 0000 0000//System.ValueType

(12)A1FA 0100 0000//System.Type

(13)CB0F 0100 0000

    //SmartCard.Runtime.Remoting.Channels.APDU.APDU

ServerChannel

(14)D9F8 0100 0000

    //System.Runtime.Remoting.Channels.ChannelServices

(15)F55B 0100 0000

    //System.Runtime.Remoting.RemotingConfiguration

上述数据均采用的是小端的表示方式,前两个字节为压缩后的引用类型的名称,中间两个字节为方法计数,后两个字节为字段计数,“//”后为.net文件中引用类型名称字符串,通过对比可以得出,本实施例所提供的方法具有较好的压缩效果,可以通过对引用类型的压缩使.net文件占用的存储空间减小,可以降低.net文件的使用受存储空间的限制。

需要说明的是,在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行,并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。

此外,上述可执行指令可以存储于存储介质中,术语“存储介质”可以表示用于存储数据的一种或多种装置,包括只读存储器(ROM)、随机存取存储器(RAM)、磁RAM、磁心存储器、磁盘存储介质、光存储介质、闪存装置和/或用于存储信息的其他机器可读介质。术语“机器可读介质”包括但不限于便携式或固定存储装置、光存储装置、无线通道或能够存储、容纳、或承载指令和/或数据的各种其他介质。

另外,可以通过硬件、软件、固件、中间件、微码、硬件描述语言或其组合来实现实施例。当用软件、固件、中间件或微码来实现时,可以在诸如存储介质的机器可读介质中存储用于执行必要任务的程序代码或码段。(多个)处理器可以执行必要任务。码段可以表示进程、函数、子程序、程序、例行程序、子例行程序、模块、对象、软件包、类、或指令、数据结构、或程序语言的任意组合。通过传输和/或接收信息、数据、自变量、或存储内容来将码段耦合到另一码段或硬件电路。信息、自变量、参数、数据等可以经由包括存储器共享、消息传递、令牌传递、网络传输等的任意合适方式来传递、传输、或传送。

显然,本领域的技术人员应该明白,上述的本发明的各模块或各步骤可以用通用的计算装置来实现,它们可以集中在单个的计算装置上,或者分布在多个计算装置所组成的网络上,可选地,它们可以用计算装置可执行的程序代码来实现,从而,可以将它们存储在存储装置中由计算装置来执行,或者将它们分别制作成各个集成电路模块,或者将它们中的多个模块或步骤制作成单个集成电路模块来实现。这样,本发明不限制于任何特定的硬件和软件结合。

以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号