RAR 版本 3.93 - 技术信息 ~~~~~~~~~~~~~~~~~~~~~~~~ 下列压缩文件格式描述仅对版本 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字节,所以只使用低位 字节。