zip文件协议&gzip文件协议

// 均要以小端字节序排列

/**
 * ZIP文件格式
 * 
 * n * 文件描述块 + 存档解密头 + 存档额外数据记录 + n * 中央目录头 + 中央目录记录的zip64结尾 + 中央目录定位符的zip64结尾 + 中央目录记录的结尾
 * 
 * 无论加密与否只需包含三个基础也可以组成标准zip文件
 * 本地文件头 + 中央目录头 + 中央目录记录结尾
 * 
 * [local file header 1]                        [本地文件头1]
 * [encryption header 1]                        [加密头1]           根据有无加密存在
 * [file data 1]                                [文件数据1]         此四部分统称为文件描述块
 * [data descriptor 1]                          [数据描述符1]       根据通用标志位bit3确定是否存在
 * .
 * .
 * .
 * [local file header n]                        [本地文件头n]
 * [encryption header n]                        [加密头n]
 * [file data n]                                [文件数据n]
 * [data descriptor n]                          [数据描述符n]
 * 
 * [archive decryption header]                  [存档解密头]
 * [archive extra data record]                  [存档额外数据记录]
 * 
 * [central directory header 1]                 [中央目录头1]
 * .
 * .
 * .
 * [central directory header n]                 [中央目录头n]
 * 
 * [zip64 end of central directory record]      [中央目录记录的zip64结尾] 
 * [zip64 end of central directory locator]     [中央目录定位符的zip64结尾]
 * [end of central directory record]            [中央目录记录的结尾]
 * 
 * 
 * 一个本地文件头对应一个中央目录头
 */

/**
 * 本地文件头组成
 * 
 * local file header signature     4 bytes      本地文件头标识符 (0x04034b50(大端)) 
 * version needed to extract       2 bytes      提取需要的版本
 * general purpose bit flag        2 bytes      通用位标志
 * compression method              2 bytes      压缩方法
 * last mod file time              2 bytes      最后修改文件时间 时分秒
 * last mod file date              2 bytes      最后修改文件日期 年月日
 * crc-32                          4 bytes      crc-32(对压缩前的文件计算)
 * compressed size                 4 bytes      压缩大小
 * uncompressed size               4 bytes      未压缩大小
 * file name length                2 bytes      文件名长度
 * extra field length              2 bytes      额外字段长度
 * file name                 (variable size)    文件名
 * extra field               (variable size)    额外字段
 */

/**
 * 通用标志位说明
 * 
 * bit 0: 设为1时表示采用了压缩算法
 * 如果压缩方法是 6
 * bit 1: 0 -> 4k滑动字典; 1 -> 8k滑动字典
 * bit 2: 0 -> 2个香农-法诺树加密滑动字典; 1 -> 3个香农-法诺树加密滑动字典
 * 
 * 如果压缩方法为 8 和 9
 * bit 2   bit 1
 *   0       0      使用了正常压缩选项。 -en
 *   0       1      使用了最大压缩选项 (-exx/-ex)
 *   1       0      使用了快速压缩选项。(-ef)
 *   1       1      使用了超快速压缩选项。(-es)
 * 
 * 压缩方法为 14
 * bit 1: 0 -> 不存在EOS标记并且必须知道压缩数据大小才能提取; 1 -> 使用EOS标记压缩数据流的结束
 * 
 * 如果为其他压缩方法
 *  b1 b2不会被用到
 * 
 * 下面不论压缩方法, 均通用
 * bit 3: 0 -> 无用; 1 -> CRC32、压缩大小、压缩前大小在本地标头中设置为0,正确的值放在数据描述符中
 * bit 4: 为压缩方法8保留,用于增强型deflating
 * bit 5: 1 -> 表明该文件是压缩的补丁数据 (需要 PKZIP 2.70 或更高版本) (当对一个超大的已压缩文件进行分块时会用到)
 * bit 6: 强加密,参阅强加密部分
 * bit 7、8、9、10、12、14、15: 保留
 * bit 11 语言编码标志 1 -> 文件名和注释字段必须使用utf8
 */

/**
 * 压缩方法说明
 * 
 * unencrypted              0
 * UnShrinking              1
 * Expanding                2-5
 * Imploding                6   // 1-6不推荐使用
 * Tokenizing               7   // This method is not used by PKZIP.
 * Deflating                8
 * Enhanced Deflating       9
 * PKWARE Data Compression Library Imploding    10
 * BZIP2                    12
 * LZMA                     14
 * IBM z/OS CMPSC Compression   16
 * IBM TERSE                18
 * IBM LZ77 z Architecture  19
 * JPEG variant             96
 * WavPack                  97
 * PPMd                     98
 * AE-x Encryption marker   99
 * 
 * Reserved                 11, 13, 15, 17
 */

/**
 * 时间说明
 * 
 * 日期和时间以标准 MS-DOS 格式编码。
 * 0 - 4    秒 (除以2得到)
 * 5 - 10   分
 * 11 - 15  时
 * 16 - 20  日
 * 21 - 24  月
 * 25 - 31  年 (减去1980年得到)
 */

/**
 * CRC32说明
 * 
 * 
 */

/**
 * 数据描述符说明
 * 
 * 存储以下三个字段,当通用标志 bit3设为1时必须存在
 *      crc-32 4 字节
 *      压缩大小 4 字节
 *      未压缩大小 4 字
 */

/**
 * 加密头
 * 
 * 12字节。经过加密的
 * 
 * 加密数据头:
 * 1、初始化加密秘钥
 *      uint32_t Key[3];
 *      Key(0) = 305419896
 *      Key(1) = 591751049
 *      Key(2) = 878082192
 * 
 * loop for i = 0 to length(password) - 1
 *     update_keys(password(i))  // update_keys定义如下
 * end loop
 * 
 * 2、读取12字节的加密头到buffer[12]
 * loop for i = 0 to 11
 *     C = buffer(i) ^ decrypt_byte()
 *     update_keys(C)
 *     buffer(i) = C
 * end loop
 *
 * 3、说明
 * 经过第二步后已解密完毕
 * 如果PKZIP版本大于2.0则buffer的最后一个字节为buffer前11个字节的CRC校验
 * 如果PKZIP版本小于2.0则buffer的最后两个字节为buffer前10个字节的CRC检验
 * 此处的CRC用于校验密码提供的是否正确
 * 
 * 
 * unsigned char decrypt_byte()
 *     local unsigned short temp
 *     temp = Key(2) | 2
 *     decrypt_byte = (temp * (temp ^ 1)) >> 8
 * end decrypt_byte
 * 
 * update_keys(uint8_t c):
 *   Key(0) = crc32(key(0), c)
 *   Key(1) = Key(1) + (Key(0) & 0xFF)
 *   Key(1) = Key(1) * 134775813 + 1
 *   Key(2) = crc32(key(2),key(1) >> 24)
 * end update_key
 * 
 * crc32(uint32_t old_crc, uint8_t c);
 */


/**
 * 中央目录文件头
 * 
 * central file header signature   4 bytes      中央文件头标识符 (0x02014b50(大端)) 
 * version made by                 2 bytes      版本
 * version needed to extract       2 bytes      提取所需的版本
 * general purpose bit flag        2 bytes      通用位标志
 * compression method              2 bytes      压缩方法
 * last mod file time              2 bytes      最后修改文件时间  时分秒
 * last mod file date              2 bytes      最后修改文件日期 年月日
 * crc-32                          4 bytes      crc-32
 * compressed size                 4 bytes      压缩大小
 * uncompressed size               4 bytes      压缩前大小
 * file name length                2 bytes      文件名长度
 * extra field length              2 bytes      额外字段长度
 * file comment length             2 bytes      文件注释长度
 * disk number start               2 bytes      磁盘号
 * internal file attributes        2 bytes      内部文件属性
 * external file attributes        4 bytes      外部文件属性
 * relative offset of local header 4 bytes      本地头的相对偏移量 (对应的本地文件相对于文件开始的偏移量)
 * 
 * file name                (variable size)     文件名
 * extra field              (variable size)     额外字段
 * file comment             (variable size)     文件注释
 */

/**
 * 提取所需的版本
 * 
 * 
 */

/**
 * 外部文件属性
 * 
 * 高位字节表示文件属性的兼容性,如果外部文件属性与MS-DOS兼容,并且可以被2.04g的DOS版本的PKZIP所读取
 * 则该值为0。如果不兼容,则该值将标识属性兼容的主机系统。
 * 
 *  0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)
 *  1 - Amiga                     2 - OpenVMS
 *  3 - UNIX                      4 - VM/CMS
 *  5 - Atari ST                  6 - OS/2 H.P.F.S.
 *  7 - Macintosh                 8 - Z-System
 *  9 - CP/M                     10 - Windows NTFS
 *  11 - MVS (OS/390 - Z/OS)      12 - VSE
 *  13 - Acorn Risc               14 - VFAT
 *  15 - alternate MVS            16 - BeOS
 *  17 - Tandem                   18 - OS/400
 *  19 - OS X (Darwin)            20 thru 255 - unused
 * 
 */

/**
 * 数字签名
 * 
 * header signature                4 bytes          数字签名标识符 (0x05054b50(大端))
 * size of data                    2 bytes          签名数据大小
 * signature data              (variable size)      签名数据
 */
 
/**
 * 中央目录记录的zip64结尾
 *
 * signature                       4 bytes  (0x06064b50)
 * size of zip64 end of central directory record                8 bytes
 * version made by                 2 bytes
 * version needed to extract       2 bytes
 * number of this disk             4 bytes
 * number of the disk with the start of the central directory  4 bytes
 * total number of entries in the central directory on this disk  8 bytes
 * total number of entries in the central directory               8 bytes
 * size of the central directory   8 bytes
 * offset of start of central directory with respect to the starting disk number        8 bytes
 * zip64 extensible data sector    (variable size)
 */

 /**
 * 中央目录定位符的zip64结尾
 *
 * signature                       4 bytes  (0x07064b50)
 * number of the disk with the start of the zip64 end of central directory	4 bytes		中央目录以zip64结尾的磁盘编号
 * relative offset of the zip64 end of central directory record 			8 bytes		中心目录记录的zip64结尾的相对偏移量
 * total number of disks           4 bytes 	磁盘总数
 */ 

/**
 * 中央目录记录结尾
 * 
 * end of central dir signature    4 bytes          中心目录结尾标识符 (0x06054b50(大端))
 * number of this disk             2 bytes          当前磁盘编号
 * number of the disk with the start of the central directory  2 bytes      目录区开始磁盘编号
 * total number of entries in the central directory on this disk  2 bytes   本磁盘上纪录总数 
 * total number of entries in the central directory           2 bytes       目录区中纪录总数
 * size of the central directory   4 bytes          目录区尺寸大小 (中央目录总的字节数)
 * offset of start of central directory with respect to the starting disk number  4 bytes
 *                                                  目录区对第一张磁盘的偏移量 (第一个中央目录区在此文件的位置(从0开始计算的值))
 * .ZIP file comment length        2 bytes          ZIP 文件注释长度
 * .ZIP file comment           (variable size)      ZIP 文件注释内容
 */
// gzip文件格式
1、总体说明
    字节序:小端
    bit 0-7: 一个字节有8位最低位为0, 最高位为7,+--------+
    |76543210|
    +--------+

2、gzip组成
    2.1、
    gzip由一系列的块组成
    块:
    +---+---+---+---+---+---+---+---+---+---+
    |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
    +---+---+---+---+---+---+---+---+---+---+

    (if FLG.FEXTRA set)
    +---+---+=================================+
    | XLEN  |...XLEN bytes of "extra field"...| (more-->)
    +---+---+=================================+

    (if FLG.FNAME set)
    +=========================================+
    |...original file name, zero-terminated...| (more-->)
    +=========================================+

    (if FLG.FCOMMENT set)
    +===================================+
    |...file comment, zero-terminated...| (more-->)
    +===================================+

    (if FLG.FHCRC set)
    +---+---+ +=======================+
    | CRC16 | |...compressed blocks...| (more-->)
    +---+---+ +=======================+

    0   1   2   3   4   5   6   7
    +---+---+---+---+---+---+---+---+
    |     CRC32     |     ISIZE     |
    +---+---+---+---+---+---+---+---+

    2.2ID1(IDentification 1) = 0x1f    (1byte)
    ID2(IDentification 2) = 0x8b    (1byte)
    用ID1和ID2来标识一个块
    CM (Compression Method)         (1byte)
    0 - 7保留
    8表示压缩方法为deflate, gzip通常用的都是这种压缩方式
    FLG (FLaGs)                     (1byte)
    bit 0   FTEXT       // 1: ASCII文本; 0: 二进制数据
    bit 1   FHCRC       // 1: CRC16(位置,压缩数据之前) CRC16由CRC32的两个最低有效字节组成,用于gzip报头的所有字节(不包括CRC16)
    bit 2   FEXTRA      // 1: 将会多一个额外字段
    bit 3   FNAME
    bit 4   FCOMMENT
    bit 5   reserved
    bit 6   reserved
    bit 7   reserved
    MTIME(Modification TIME)        (4byte)
    修改时间, unix时间戳
    自[1970/01/01 00:00:00]以来的秒数
    为0时表示无效
    XFL(eXtra field FLag)           (1byte)
    仅当CM == 8时有用
    XFL = 2 - 压缩器用于最大压缩,最慢算法
    XFL = 4 - 使用最快算法的压缩器
    OS(Operating System)            (1byte)
    0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
    1 - Amiga
    2 - VMS (or OpenVMS)
    3 - Unix
    4 - VM/CMS
    5 - Atari TOS
    6 - HPFS filesystem (OS/2, NT)
    7 - Macintosh
    8 - Z-System
    9 - CP/M
    10 - TOPS-20
    11 - NTFS filesystem (NT)
    12 - QDOS
    13 - Acorn RISCOS
    255 - unknown
    XLEN(eXtra LENgth)              (2byte)
    仅当FLG.FEXTRA设置才会存在
    CRC32(CRC-32)                   (4byte)
    对未压缩数据进行CRC32检验
    ISIZE(Input SIZE)               (4byte)
    未压缩数据字节数

    2.3、
    Extra field
    +---+---+---+---+==================================+
    |SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
    +---+---+---+---+==================================+
    SI1(subfield ID) = 0x41('A') (1byte)
    SI2(subfield ID) = 0x70('P') (1byte)
    LEN(length) (2byte)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值