有没有办法检查缓冲区是否为 Brotli 压缩格式?

Is there a way to check if a buffer is in Brotli compressed format?

我是一名实习生,正在研究在软件中使用 Brotli 压缩是否比使用 GZip 的当前版本提高性能。

我的任务是将使用 GZip 的任何内容更改为使用 Brotli 压缩。我需要替换的一个函数执行检查以测试缓冲区是否包含使用 GZip 压缩的数据。它通过检查开始和结束的流标识符来做到这一点:

bool isGzipped() const
{
    // Gzip file signature (0x1f8b)
    return
        (_bufferEnd >= _bufferStart + 2) &&
        (static_cast<unsigned char>(_bufferStart[0]) == 0x1f) &&
        (static_cast<unsigned char>(_bufferStart[1]) == 0x8b);
}

我想创建类似的功能bool isBrotliEncoded()。我想知道是否可以使用 Brotli 编码缓冲区进行类似的快速检查?我查看了 brotli 生成的一些压缩文件的字节值,但我找不到适用于所有这些文件的规则。有些以 0x5B 开头,有些以 0x1B 开头,空文件的压缩结果为 0x06,并且多次压缩的文件以一系列不同的值开头。每个文件的结尾也不一致。

我所知道的测试格式是否正确的唯一方法是尝试解压并等待错误,这违背了进行此测试的目的。

所以我的问题是:有谁知道如何在不尝试解压缩和等待失败的情况下检查缓冲区是否已用 Brotli 压缩?

Brotli 在 RFC 7932. The format of the data stream is covered in Section 2: Compressed Representation Overview and Section 9: Compressed Data Format. Brotli does not employ leading/trailing identifiers like gzip does, but it does consist of a sequence of uncompressed headers and commands that describe the compressed data. They are not all aligned on byte boundaries, you have to parse them at the bit level instead (Brotli is processed as a stream of bits and bytes). Refer to Section 10: Decoding Algorithm 中正式定义了如何阅读这些 headers。如果您解析出一些遵循 Brotli 格式的 headers 而没有错误,那么您很可能正在处理 Brotli 压缩缓冲区。

不幸的是,原始 brotli 格式不太适合这种检测,即使只是尝试解压缩并等待错误也是如此。

我运行 对 运行dom 数据进行了一百万次 brotli 解压缩的试验。其中大约 5% 的 brotli 流被签出。所以你已经遇到了问题。百万中的 3.5% 是单个字节,因为有九个 one-byte 个值都是有效的 brotli 流。 运行dom 有效流的平均长度几乎是一兆字节。

对于那些检测到错误的案例(大约 95% 的百万案例),3.5% 的案例在检测到错误之前超过了 1 兆字节。 1.4% 超过了 10 兆字节。发现错误前的平均 运行dom 字节数是 309 KB。另一个问题。

简而言之,误报的概率比较高,要处理的字节数可能会很大。

如果您正在编写此软件,那么您应该将自己的 header 放在 brotli 数据之前以帮助检测。或者你可以使用 brotli framing format that I developed at their request,它在 brotli 压缩流之前有一个独特的 four-byte header。这将大大降低误报的可能性。