【问题标题】:walking through deflate by hand用手通过放气
【发布时间】:2022-01-20 14:16:35
【问题描述】:

我正在尝试了解 deflate 的工作原理。也就是说,我想我会尝试手动解码一个放气编码的字符串,而不是RFC1951: DEFLATE Compressed Data Format Specification version 1.3 所说的。我因此生成了deflate编码的字符串:

$result = gzdeflate('A_DEAD_DAD_CEDED_A_BAD_BABE_A_BEADED_ABACA_BED');

echo bin2hex($result);

这给了我这个:

1589c11100000cc166a3cc61ff2dca237709880c45e52c2b08eb043dedb78db8851e

来自 RFC1951 § 3.2.3。块格式的详细信息:

         Each block of compressed data begins with 3 header bits
         containing the following data:

            first bit       BFINAL
            next 2 bits     BTYPE

...

         BFINAL is set if and only if this is the last block of the data
         set.

         BTYPE specifies how the data are compressed, as follows:

            00 - no compression
            01 - compressed with fixed Huffman codes
            10 - compressed with dynamic Huffman codes
            11 - reserved (error)

0x15 是 0b00010101 位。前 3 位是 000,这将使 BFINAL 0 和 BTYPE 00(不压缩)。

从后面的 RFC1951 § 3.2.3 开始。块格式的详细信息:

           if stored with no compression
              skip any remaining bits in current partially
                 processed byte
              read LEN and NLEN (see next section)
              copy LEN bytes of data to output

来自 RFC1951 § 3.2.4。非压缩块(BTYPE=00):

     Any bits of input up to the next byte boundary are ignored.
     The rest of the block consists of the following information:

          0   1   2   3   4...
        +---+---+---+---+================================+
        |  LEN  | NLEN  |... LEN bytes of literal data...|
        +---+---+---+---+================================+

     LEN is the number of data bytes in the block.  NLEN is the
     one's complement of LEN.

所以我移动到下一个字节 - 0x89,即 0b10001001 位。前两位 (LEN) 是 10,接下来的两位是 NLEN (00)。但问题就在这里。 00 不是 10 的补码 - 01 是。

另外,如果你想要一个以 0xFF 作为第一个字节的未压缩块怎么办?这不可能吗?

【问题讨论】:

  • 我不明白为什么你认为你不能将0xff 作为第一个未压缩字节。

标签: php deflate


【解决方案1】:

您没有阅读 RFC 的这一部分:

数据元素按比特数递增的顺序打包成字节 在字节内,即从最低有效位开始 字节。

前三位是101,而不是000

使用infgen对该流进行解码:

! infgen 2.6 output
!
last
dynamic
count 259 10 16
code 17 4
code 18 3
code 0 4
code 4 3
code 3 1
code 2 3
zeros 65
lens 3 3 4 3 3
zeros 25
lens 3
zeros 138
zeros 22
lens 4 3 3
zeros 3
lens 2 0 0 2 2 3 3
! litlen 65 3
! litlen 66 3
! litlen 67 4
! litlen 68 3
! litlen 69 3
! litlen 95 3
! litlen 256 4
! litlen 257 3
! litlen 258 3
! dist 3 2
! dist 6 2
! dist 7 2
! dist 8 3
! dist 9 3
literal 'A_DEAD_D
match 3 4
literal 'CEDED_A_B
match 3 12
literal 'BABE
match 4 11
match 3 28
match 4 20
literal 'BAC
match 4 13
literal 'D
end

【讨论】:

  • infgen 非常棒!我最喜欢infgen -ddis 输出。谢谢你指点我!
猜你喜欢
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 2018-08-21
相关资源
最近更新 更多