声明:本文并非百分百原创,乃是对两位前辈已有工作的补充与完善,两位前辈的成果在参考链接里。
参考链接: http://wenku.baidu.com/view/3caf8f11866fb84ae45c8de5.html rar文档结构分析
http://wenku.baidu.com/view/b7889b64783e0912a2162aa4.html RAR文件格式的研究
本文已上传,下载链接为: http://download.csdn.net/detail/ping_fani07/5353575
RAR version 3.40 - Technical information
RAR 3.40版 技术信息
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
THE ARCHIVE FORMAT DESCRIBED BELOW IS ONLY VALID FOR VERSIONS SINCE 1.50
下面对归档文件格式的描述仅仅是对
1.5
以后的版本是有
效的
=======================================================================================================
RAR archive file format
RAR归档文件格式
=======================================================================================================
Archive file consists of variable length blocks.
归档文件是由可变长度的块组成的。
The order of these blocks may vary, but the first block must be a marker block followed by an archive header block.
这些块之间没有固定地先后顺序,但是要求第一个块必须是被一个归档头部块紧跟的标志块
【译者注:即第一个块是标志块,并且其后紧跟一个归档头部块】。
Each block begins with the following fields:
每一个块都是由以下域开始的:
【译者注:即每一个块的头部都是由以下域(可称之为头域)组成的】
HEAD_CRC 2 bytes CRC of total block or block part
整个块或者块某个部分的CRC(根据块类型而有不同)
HEAD_TYPE 1 byte Block type
块类型
【译者注:也可以理解为块头部类型,因为不同的块对应不同的块头部。后文也经常混淆这两种概念。】
HEAD_FLAGS 2 bytes Block flags
块标志
HEAD_SIZE 2 bytes Block size
块大小
【译者注:本文中和块头部大小的概念一直混淆。后文中当遇到标志块、结尾块等只有头部的块时,也可理解为块头部大小】
ADD_SIZE 4 bytes Optional field - added block size
添加块的大小(这是一个可选域)
Field ADD_SIZE present only if (HEAD_FLAGS & 0x8000) != 0
头域ADD
_SIZE仅当(
HEAD_FLAGS & 0x8000) != 0
【译者注:即块标志的首位被置
1
】
的时候才会存在
Total block size is HEAD_SIZE if (HEAD_FLAGS & 0x8000) == 0
当(
HEAD_FLAGS & 0x8000) == 0
【译者注:即块标志的首位被置
0
】
的时候,整个块的大小就是HEAD_SIZE
and HEAD_SIZE+ADD_SIZE if the field ADD_SIZE is present - when (HEAD_FLAGS & 0x8000) != 0.
而当(
HEAD_FLAGS & 0x8000) != 0
【译者注:即块标志的首位被置
1
】
的时候,整个块的大小就是(HEAD_SIZE+ADD_SIZE)
In each block the followings bits in HEAD_FLAGS have the same meaning:
HEAD_FLAGS域【块标志】的以下几位在每一个块中都有相同的含义:
0x4000 - if set, older RAR versions will ignore the block and remove it when the archive is updated.
【高二位】
(此位)如果置为
1
,老版本的
rar
会在
归档文件更新的时候忽略这个块,并且移除这个块。
if clear, the block is copied to the new archive file when the archive is updated;
如果清为
0
,那么当更新的时候,这个块会被复制到新的归档文件中
0x8000 - if set, ADD_SIZE field is present and the full block size is HEAD_SIZE+ADD_SIZE.
【最高位】
(此位)如果置为
1
,就会存在ADD_SIZE这个域,并且整个块的大小就应该是(HEAD_SIZE+ADD_SIZE)
Declared block types:
已经声明过的块类型包括:
HEAD_TYPE=0x72 marker block【译者注:有些文献里也称之为
MARK_HEAD
】
标志块
【译者注:一个固定为0x52 61 72 21 1A 07 00的7字节序列】
HEAD_TYPE=0x73 archive header【译者注:有些文献里也称之为
MAIN_HEAD
】
归档头部块
HEAD_TYPE=0x74 file header【译者注:有些文献里也称之为
FILE_HEAD
】
文件块
【译者注:直译为文件头部,但是此处的类型应该指的是整个块的类型,而非块头部结构的类型,因此感觉称之为文件块更合适。】
HEAD_TYPE=0x75 old style comment header
老风格的 注释块
【译者注:直译为注释头部,基于和文件块一样的原因,感觉称之为注释块更合适】
HEAD_TYPE=0x76 old style authenticity information
老风格的 授权信息块
/
用户身份信息块
HEAD_TYPE=0x77 old style subblock
老风格的 子块
HEAD_TYPE=0x78 old style recovery record
老风格的 恢复记录块
HEAD_TYPE=0x79 old style authenticity information
老风格的 授权信息块
/
用户身份信息块
HEAD_TYPE=0x7a subblock
子块
HEAD_TYPE=0x7b end block
结束块
【译者注:一个固定为0xC4 3D 7B 00 40 07 00的7字节序列】
Comment block is actually used only within other blocks and doesn't exist separately.
注释块实际上只在其它块中使用,并不单独存在
Archive processing is made in the following manner:
归档
文件的处理遵循以下流程:
1. Read and check marker block
读取和检查标志块
【译者注:确认这是一个
rar
格式的归档文件】
2. Read archive header
读取归档头部块的信息
3. Read or skip HEAD_SIZE-sizeof(MAIN_HEAD) bytes
读取或者是跳过HEAD_SIZE( 即sizeof(MAIN_HEAD) )个字节的内容
【译者注:即跳过归档头部块,将指针指向下一个块,也就是文件块的开始位置,然后读取紧接下来的 7 字节。另外,译者觉得句首的“读取”不知所云,第二步明明已经读取,此步应该只要跳过就好。 】
4. If end of archive encountered then terminate archive processing,
如果遇到归档文件结束标志
【译者注:即下一个块是结束块】,
那么终止归档文件处理过程,
else read 7 bytes into fields HEAD_CRC, HEAD_TYPE, HEAD_FLAGS, HEAD_SIZE.
不然的话,读取7
个字节
到头部的四个域:HEAD_CRC
,
HEAD_TYPE
,
HEAD_FLAGS
,
HEAD_SIZE
中。
5.循环处理
Check HEAD_TYPE.
检查头部的HEAD_TYPE域 【译者注:此域指定块类型】
if HEAD_TYPE==0x74如果HEAD_TYPE域的值是0x74 【译者注:表明是文件块】
read file header ( first 7 bytes already read )
读取文件块(前 7 个字节已经读过)
read or skip HEAD_SIZE-sizeof(FILE_HEAD) bytes
读取或者跳过HEAD_SIZE( 即sizeof(MAIN_HEAD) )个字节的内容
if (HEAD_FLAGS & 0x100)如果块标志的第四位被置为 1 (即 HEAD_FLAGS & 0x0100 !=0) 【译者注:说明HIGH_PACK_SIZE这个头域存在】
read or skip HIGH_PACK_SIZE*0x100000000+PACK_SIZE bytes
读取或者跳过已压缩文件大小(即HIGH_PACK_SIZE*0x100000000+PACK_SIZE)的字节【译者注:HIGH_PACK_SIZE是文件块头部的可选域,是已压缩文件大小 64 位值的高 4 字节,仅当文件较大时存在。 】
else
read or skip PACK_SIZE bytes
读取或者跳过已压缩文件大小(即PACK_SIZE)的字节
else
read corresponding HEAD_TYPE block:
读取HEAD_TYPE所指定类型的块的内容;
read HEAD_SIZE-7 bytes读取HEAD_SIZE-7个字节的内容 【译者注:即块数据部分】
if (HEAD_FLAGS & 0x8000)如果( HEAD_FLAGS & 0x8000) != 0 【译者注:即块标志的首位被置 1 ,亦即说明添加块存在】
read ADD_SIZE bytes读取ADD_SIZE个字节 【译者注:即添加块的内容】
6. go to 4.
转到第
4
步
=======================================================================================================
Block Formats
(常见)块格式
=======================================================================================================
Marker block ( MARK_HEAD )
标志块
HEAD_CRC 2 bytes Always 0x6152
HEAD_TYPE 1 byte Header type: 0x72
HEAD_FLAGS 2 bytes Always 0x1a21
HEAD_SIZE 2 bytes Block size = 0x0007
The marker block is actually considered as a fixed byte sequence: 0x52 0x61 0x72 0x21 0x1a 0x07 0x00
标志块事实上被认为是一个固定地字节序列:0x52 0x61 0x72 0x21 0x1a 0x07 0x00
Archive header ( MAIN_HEAD )
归档头部块
HEAD_CRC 2 bytes CRC of fields HEAD_TYPE to RESERVED2
从头域HEAD_TYPE到头域RESERVED2的CRC
HEAD_TYPE 1 byte Header type: 0x73
HEAD_FLAGS 2 bytes Bit flags:
0x0001 - Volume attribute (archive volume)
【最低位】
卷属性
标志(归档文件卷)
0x0002 - Archive comment present
【低二位】
注释标志
。【此位若被置
1
,注释存在
】
RAR 3.x uses the separate comment block and does not set this flag.
RAR 3系列的版本使用独立的注释块(来描述归档内容),这个标志没有设定
0x0004 - Archive lock attribute
【低三位】
归档锁属性
标志
0x0008 - Solid attribute (solid archive)
【低四位】
“
固
实”
属性
标志
【译者注:此位若被置
1
,则使用了固实模式压缩】
0x0010 - New volume naming scheme ('volname.partN.rar')
【低五位】
新卷命名方案
存在标志
【译者注:可否理解为,多卷压缩的时候,其他卷里的文件命名方案】
0x0020 - Authenticity information present
【低六位】
授权信息
存在标志
。【译者注:此位若被置
1
,
授权信息存在】
RAR 3.x does not set this flag.
RAR 3系列的版本没有设定这个标志
0x0040 - Recovery record present
【低七位】
回复记录存在标志
。【译者注:此位若被置
1
,则
恢复记录存在】
0x0080 - Block headers are encrypted
【低八位】
块头加密标志
。【译者注:此位若被置
1
,则
块头是被加密的】
0x0100 - First volume (set only by RAR 3.0 and later)
【高八位】
首卷标志(只有
RAR3.0
以后的版本
会设置此位
)【译者注:此位若被置
1
,
则此卷为首卷】
other bits in HEAD_FLAGS are reserved for internal use
其他的位为内部使用保留
HEAD_SIZE 2 bytes Archive header total size including archive comments
归档头部块大小,包括归档文件注释
。【译者注:不知此处的注释是否指归档头部块的注释块】
RESERVED1 2 bytes Reserved
保留域
RESERVED2 4 bytes Reserved
保留域
File header (File in archive)
文件块(被归档的文件)
HEAD_CRC 2 bytes CRC of fields from HEAD_TYPE to FILEATTR and file name
从头域HEAD_TYPE到头域FILEATTR的CRC
HEAD_TYPE 1 byte Header type: 0x74
HEAD_FLAGS 2 bytes Bit flags:
0x01 - file continued from previous volume
前文存在标志
。【译者注:此位若被置
1
,则
文件从前一个卷继续】
0x02 - file continued in next volume
后文存在标志
。【译者注:此位若被置
1
,则
文件在后一个卷继续】
0x04 - file encrypted with password
加密标志
。【译者注:此位若被置
1
,则
文件使用了基于密钥的加密】
0x08 - file comment present
注释存在标志
。【译者注:此位若被置
1
,则
文件注释存在】
RAR 3.x uses the separate comment block and does not set this flag.
RAR 3系列的版本使用独立的注释块(来描述归档内容),这个标志没有设定
0x10 - information from previous files is used (solid flag) (for RAR 2.0 and later)
固实标志。此位若被置
1
,则
之前的文件信息被使用(
RAR2.0
及其以后的版本可用)
bits 7 6 5 (for RAR 2.0 and later)【译者注:原文应该是从
0
开始计数,故此是
0x20、0x40
、
0x80
】
第5
、
6
、
7
位表示的是字典的大小(
RAR2.0及其以后的版本可用)
【译者注:按照译者前文的计数习惯,应该是
6
、
7
、
8
位】
0 0 0 - dictionary size 64 KB
0 0 1 - dictionary size 128 KB
0 1 0 - dictionary size 256 KB
0 1 1 - dictionary size 512 KB
1 0 0 - dictionary size 1024 KB
1 0 1 - dictionary size 2048 KB
1 1 0 - dictionary size 4096 KB
1 1 1 - file is directory 【译者注:以整个文件作为字典】
0x100 - HIGH_PACK_SIZE and HIGH_UNP_SIZE fields are present.
大文件标志
。【译者注:此位若被置
1
,则
头域HIGH_PACK_SIZE 和 HIGH_UNP_SIZE存在。】
These fields are used to archiveonly very large files (larger than 2Gb), for smaller files these fields are absent.
这些头域仅用于归档很大(大于
2GB
)文件的时候,对于不足2GB的小文件,这些头域是不存在的。
0x200 - FILE_NAME contains both usual and encoded Unicode name separated by zero.
此位若被置
1
,则
FILE_NAME同时包括了通常的文件名和用0
隔开的以
Unicode编码的文件名
In this case NAME_SIZE field is equal to the length of usual name plus encoded Unicode name plus 1.
在这种情况下,NAME_SIZE 头域的值就该等于:通常的文件名长度+以Unicode编码的文件名长度+
1
。
0x400 - the header contains additional 8 bytes after the file name, which are required to increase encryption security (so called 'salt').
强安全性标志。此位若被置
1
,则
头部在文件名之后还会再附加8
个字节
用来增强加密强度(这被称之为“盐”
【译者注:一个密码学概念,可理解为干扰因子】)
0x800 - Version flag. It is an old file version, a version number is appended to file name as ';n'.
版本标志。此位若被置
1
,则
这是一个老版本的文件,版本号以”;n”的形式被附加到文件名后。
0x1000 - Extended time field present.
扩展时间头域存在标志
。【译者注:此位若被置
1
,则
存在扩展的时间头域】
0x8000 - this bit always is set, so the complete block size is HEAD_SIZE + PACK_SIZE(and plus HIGH_PACK_SIZE, if bit 0x100 is set)
数据长度头域存在标志
。【译者注:此位若被置
1
,则
头域PACK_SIZE存在】
此位通常都会被置为1,因此完整的块大小是HEAD_SIZE + PACK_SIZE(
如果
位0x100被设定的话,那么还要加上HIGH_PACK_SIZE)
HEAD_SIZE 2 bytes File header full size including file name and comments
文件块大小,包括文件名和内容
PACK_SIZE 4 bytes Compressed file size
压缩后的文件大小
【译者注:亦即前文所说的数据长度头域】
UNP_SIZE 4 bytes Uncompressed file size
没有压缩之前的文件大小
HOST_OS 1 byte Operating system used for archiving
归档(压缩)操作时所在的操作系统
0 - MS DOS
1 - OS/2
2 - Win32
3 - Unix
4 - Mac OS
5 - BeOS
FILE_CRC 4 bytes File CRC
被归档文件的CRC
【译者注:不知是压缩前还是压缩后】
FTIME 4 bytes Date and time in standard MS DOS format
标准MS DOS格式的时间和日期
UNP_VER 1 byte RAR version needed to extract file
释放(即解压)文件所需要的
RAR
(最低)版本
Version number is encoded as 10 * Major version + minor version.
版本号的是编码方式是:10*主版本号+小版本号
METHOD 1 byte Packing method
打包方式
【译者注:可理解为压缩模式】
0x30 - storing 存储
0x31 - fastest compression 最快压缩
0x32 - fast compression
快压缩
0x33 - normal compression
普通压缩
0x34 - good compression
好压缩
0x35 - best compression
最好压缩
NAME_SIZE 2 bytes File name size
文件名长度
ATTR 4 bytes File attributes
文件属性
HIGH_PACK_SIZE 4 bytes High 4 bytes of 64 bit value of compressed file size.
已压缩文件大小的
64
位值的高位四字节
Optional value, presents only if bit 0x100 in HEAD_FLAGS is set.
可选的头域,仅当块标志的0x100位被置为1
时才存在
。
HIGH_UNP_SIZE 4 bytes High 4 bytes of 64 bit value of uncompressed file size.
未压缩文件大小的
64
位值的高位四字节
Optional value, presents only if bit 0x100 in HEAD_FLAGS is set.
可选的头域,仅当块标志的0x100位被置为1
时才存在
。
FILE_NAME NAME_SIZE File name - string of NAME_SIZE bytes size
文件名(所占字节数由头域NAME_SIZE指定)
SALT 8 bytes present if (HEAD_FLAGS & 0x400) != 0
盐。仅当块标志的0x100位被置为1
时才存在
EXT_TIME variable size present if (HEAD_FLAGS & 0x1000) != 0
大小可变 扩展的时间头域。仅当块标志的0x1000位被置为1
时才存在。
other new fields may appear here.
其他新加的头域可能在这里出现
======================================================================================================
Application notes
应用注意事项
======================================================================================================
1. To process an SFX archive you need to skip the SFX module searching for the marker block in the archive.
处理一个自解压缩文件的时候,你需要忽略 SFX 模块对于标志块的检查 。
There is no marker block sequence (0x52 0x61 0x72 0x21 0x1a 0x07 0x00) in the SFX module itself.
在自解压模块自身不存在标志块序列(0x52 0x61 0x72 0x21 0x1a 0x07 0x00)
2. The CRC is calculated using the standard polynomial 0xEDB88320.
CRC的值由标准的多项式0XEDB88320计算得出。
In case the size of the CRC is less than 4 bytes, only the low order bytes are used.
在
CRC
的长度被要求少于
4
字节
的情况下,只使用低
4
字节
。