您要问的是如何将代码的描述发送给接收者,以便接收者知道如何解码以下代码值。
有多种方法可以实现不同程度的复杂程度,具体取决于您要投入多少精力来压缩代码描述。 Peter de Rivaz 描述了 JPEG 使用的一种简单方法,即发送 16 个计数的每个长度的代码数量,然后是每个符号的字节值。因此,对于您的代码(十六进制):
00 03 02 00 00 00 00 00 00 00 00 00 00 00 00 00 41 42 43 44 45
这不是非常紧凑,它不能代表可能的代码之一,即 256 个 8 位代码,因为每个长度的计数限制为 255。
当你有一个完整的代码时,你可以做的第一件事就是切断代码长度。计算剩下多少个代码模式很容易,在这种情况下,您可以在没有剩余代码模式时简单地结束它。跟随符号。然后你有:
00 03 02 41 42 43 44 45
每个计数不需要 8 位,因为它们受到这些计数的限制。例如,您不能有两个以上的一位代码。所以我们可以用更少的位对这些进行编码,例如n+1 位用于 n 个代码。所以两位,三位,位,等等,直到代码完成。对于您的代码,现在是二进制:
00 011 0010
后跟字节41 42 43 44 45,在位流中适当偏移。现在计数列表采用 9 位而不是 24 位。由于我们知道只能有 256 个符号,我们可以将每个计数的位数限制为 9,允许计数 256,解决之前的问题能够表示平面代码。然后,如果代码长度限制为 16 位(对于 JPEG 也是如此),则计数所需的最大字节数为 14.5,小于原来的 16。通常计数将在 14.5 字节之前结束。
您可以变得更加复杂,注意在每个代码长度下,由于使用向上模式的代码长度较短,您对该长度的代码的可能计数有限制。然后每个计数的位数可以根据有多少可能的值而变化。那么计数描述将是:
00 011 10,然后是八位值41 42 43 44 45
由于我们没有用完长度为 1 和 2 的先前模式,因此它们仍然需要分别为 2 位和 3 位。但是,对于长度 3,我们现在只剩下三种可能性:计数 0、1 或 2。计数为 3 会超额订阅代码。所以我们可以为最后一个使用两位。现在是 7 位而不是 9 位,这大大减少了使用较长代码长度的代码的计数位数。
一种完全不同的方案是 deflate 格式使用的方案(用于 zip、gzip、zlib、png 等)。首先发送要遵循的代码长度数,然后是每个符号的代码长度,直到最后一个。符号本身由代码长度位置隐含。这会产生很多零,以表示不存在的符号。因此,对于您的代码,将有一个 70 上升到符号 69(“E”),然后是 65 个零,然后是 2 2 2 3 3。这看起来非常长,而且确实如此。放气然后运行长度和霍夫曼编码该长度列表,以压缩它。长的零字符串被压缩为几位,而短的长度也只有几位。因此,您必须先发送代码长度代码长度代码(!)的描述,以便您可以对其进行解码。
您可以阅读deflate specification 以获取有关该方案的更多信息。 brotli 使用类似的方案,但更复杂。