
                          RAR 版本 3.90 - 技术信息
                          ~~~~~~~~~~~~~~~~~~~~~~~~

                 下列压缩文件格式描述仅对版本 1.50 之后有效

============================================================================
                              RAR 压缩文件格式
============================================================================

   压缩文件由可变长度的块组成。这些块的顺序可以变化，但是第一块必须是一个在压
缩文件头后的标记块。

   每一块由下列结构开始:

HEAD_CRC       2 字节    所有块或块部分的 CRC
HEAD_TYPE      1 字节    块类型
HEAD_FLAGS     2 字节    块标记
HEAD_SIZE      2 字节    块大小
ADD_SIZE       4 字节    可选结构 - 增加块大小

   只有 (HEAD_FLAGS & 0x8000) != 0 时 ADD_SIZE 才存在

   如果 (HEAD_FLAGS & 0x8000) == 0 则总块大小是 HEAD_SIZE，当
(HEAD_FLAGS & 0x8000) != 0 时，如果 ADD_SIZE 结构存在，则总块大小是
HEAD_SIZE+ADD_SIZE。

   在每一块中 HEAD_FLAGS 的下列位都有相同的意义:

  0x4000 - 如果设置，当更新时旧的 RAR 版本将忽略这个块并删除它。
           如果清除，当更新时块被复制到新的压缩文件;

  0x8000 - 如果设置，ADD_SIZE 结构存在，全部块的大小是 HEAD_SIZE+ADD_SIZE。

  公开的块类型:

HEAD_TYPE=0x72          标记块
HEAD_TYPE=0x73          压缩文件头
HEAD_TYPE=0x74          文件头
HEAD_TYPE=0x75          旧风格的注释头
HEAD_TYPE=0x76          旧风格的用户身份信息
HEAD_TYPE=0x77          旧风格的子块
HEAD_TYPE=0x78          旧风格的恢复记录
HEAD_TYPE=0x79          旧风格的用户身份信息
HEAD_TYPE=0x7a          子块

   注释块实际上只在其它块中使用，并不存在单独的块。

   压缩文件处理由下列步骤组成:

1. 读取和检查标记块
2. 读取压缩文件头
3. 读取或跳过 HEAD_SIZE-sizeof(MAIN_HEAD) 字节
4. 如果发现压缩文件结尾则压缩文件处理终止，否则读取7字节到结构 HEAD_CRC，
   HEAD_TYPE，HEAD_FLAGS，HEAD_SIZE 中。
5. 检查 HEAD_TYPE。
   if HEAD_TYPE==0x74
     读取文件头 ( 开始的 7 字节必须读取)
     读取或跳过 HEAD_SIZE-sizeof(FILE_HEAD) 字节
     if (HEAD_FLAGS & 0x100)
       读取或跳过 HIGH_PACK_SIZE*0x100000000+PACK_SIZE 字节
     else
       读取或跳过 PACK_SIZE 字节
   else
     读取 corresponding HEAD_TYPE 块:
       读取 HEAD_SIZE-7 字节
       if (HEAD_FLAGS & 0x8000)
         读取 ADD_SIZE 字节
6. 继续 4。


 =====================================================================
                               块格式
 =====================================================================


   标记块 ( MARK_HEAD )


HEAD_CRC        总是 0x6152
2 字节

HEAD_TYPE       头类型: 0x72
1 字节

HEAD_FLAGS      总是 0x1a21
2 字节

HEAD_SIZE       块大小 = 0x0007
2 字节

   标记块实际上包含一个固定字节序列: 0x52 0x61 0x72 0x21 0x1a 0x07 0x00


   压缩文件头 ( MAIN_HEAD )


HEAD_CRC        HEAD_TYPE 到 RESERVED2 的 CRC 结构
2 字节

HEAD_TYPE       头类型: 0x73
1 字节

HEAD_FLAGS      位标记:
2 字节
                0x0001  - 卷属性(压缩文件卷)
                0x0002  - 压缩文件注释存在
                          RAR 3.x 使用分开的注释块，不设置这个标记。

                0x0004  - 压缩文件锁定属性
                0x0008  - 固实属性 (固实压缩文件)
                0x0010  - 新的卷命名法则 ('volname.partN.rar')
                0x0020  - 用户信息存在
                          RAR 3.x 不设置这个标记。

                0x0040  - 恢复记录存在
                0x0080  - 块头被加密
                0x0100  - 第一卷(只有 RAR 3.0 及以后版本设置)

                其中的其它位为内部使用保留

HEAD_SIZE       压缩文件头总大小（包括压缩文件注释）
2 字节

RESERVED1       保留
2 字节

RESERVED2       保留
4 字节



   文件头 (压缩文件中的文件)


HEAD_CRC        从 HEAD_TYPE 到 FILEATTR 的 CRC 结构和文件名
2 字节        

HEAD_TYPE       头类型: 0x74
1 字节

HEAD_FLAGS      位标记:
2 字节
                0x01 - 文件在前一卷中继续
                0x02 - 文件在后一卷中继续
                0x04 - 文件使用密码加密

                0x08 - 文件注释存在
                       RAR 3.x 使用分开的注释块，不设置这个标记。

                0x10 - 前一文件信息被使用(固实标记)
                       (对于 RAR 2.0 和以后版本)

                     7 6 5 位(对于 RAR 2.0 和以后版本)

                     0 0 0    - 字典大小   64 KB
                     0 0 1    - 字典大小  128 KB
                     0 1 0    - 字典大小  256 KB
                     0 1 1    - 字典大小  512 KB
                     1 0 0    - 字典大小 1024 KB
                     1 0 1    - 字典大小 2048 KB
                     1 1 0    - 字典大小 4096 KB
                     1 1 1    - 文件作为字典

               0x100 - HIGH_PACK_SIZE 和 HIGH_UNP_SIZE 结构存在。这些结构仅用
                       在非常大(大于 2GB)的文档，对于小文件这些结构不存在。

               0x200 - FILE_NAME 包含用 0 隔开的普通的和 Unicode 编码的文件名。
                       所以 NAME_SIZE 结构长度等于普通文件名的长度加 Unicode 
                       编码文件名的长度再加1。

                       如果此标记存在，单 FILE_NAME 不包含 0 字节，它意味文件
                       使用 UTF-8 编码。

               0x400 - 头在文件名后包含附加的8位，它对于增加加密的安全性是必需
                       的。(所谓的'Salt')。

               0x800 - 版本标记。他是老文件版本，版本号作为';n'附加到文件名后。

              0x1000 - 扩展时间区域存在。

              0x8000 - 此位总被设置，所以完整的块的大小是HEAD_SIZE + PACK_SIZE
                       (如果 0x100 位被设置，再加上 HIGH_PACK_SIZE)

HEAD_SIZE       文件头的全部大小(包含文件名和注释)
2 字节

PACK_SIZE       已压缩文件大小
4 字节

UNP_SIZE        未压缩文件大小
4 字节

HOST_OS         保存压缩文件使用的操作系统
1 字节                 0 - MS DOS
                       1 - OS/2
                       2 - Win32
                       3 - Unix
                       4 - Mac OS
                       5 - BeOS

FILE_CRC        文件 CRC
4 字节

FTIME           MS DOS 标准格式的日期和时间
4 字节

UNP_VER         解压文件所需要最低 RAR 版本
1 字节
                版本编码方法 10 * 主版本 + 副版本。

METHOD          压缩方式
1 字节
                0x30 - 存储
                0x31 - 最快压缩
                0x32 - 快速压缩
                0x33 - 标准压缩
                0x34 - 较好压缩
                0x35 - 最好压缩

NAME_SIZE       文件名大小
2 字节

ATTR            文件属性
4 字节

HIGH_PACK_SIZE  压缩文件大小 64 位值的高4字节。可选值，只有 HEAD_FLAGS 中的
4 字节          0x100 位被设置才存在。

HIGH_UNP_SIZE   未压缩文件大小64位值的高4字节。可选值，只有 HEAD_FLAGS 中的
4 字节          0x100 位被设置才存在。

FILE_NAME       文件名 - NAME_SIZE 字节大小字符串


SALT            如果 (HEAD_FLAGS & 0x400) != 0 则存在
8 字节

EXT_TIME        如果 (HEAD_FLAGS & 0x1000) != 0 则存在
可变大小

其他新的区域可以显示在这里。

 ==========================================================================
                              应用程序注意事项
 ==========================================================================

   1. 处理自解压压缩文件时，你需要在压缩文件中搜索标记块跳过自解压模块。自解压
模块本身没有标记块序列(0x52 0x61 0x72 0x21 0x1a 0x07 0x00)。

   2. CRC 计算使用标准公式 0xEDB88320。由于 CRC 大小小于4字节，所以只使用低位
字节。
