4

我是一名实习生,正在研究在软件中使用 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 压缩?

4

2 回答 2

9

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

我对随机数据进行了 100 万次 brotli 解压试验。其中大约 5% 的人被视为良好的 brotli 流。所以你已经有问题了。百万中的 3.5% 是单字节,因为有九个单字节值,每一个都是有效的 brotli 流。随机有效流的平均长度几乎是一兆字节。

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

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

如果您正在编写此软件,那么您应该将自己的标题放在 brotli 数据之前以帮助检测。或者您可以使用我根据他们的要求开发的 brotli 帧格式,它在 brotli 压缩流之前有一个唯一的四字节标头。这将大大降低误报的可能性。

于 2016-08-19T05:58:11.667 回答
2

Brotli 在RFC 7932中正式定义。数据流的格式在第 2 节:压缩表示概述第 9 节:压缩数据格式中介绍。Brotli 不像 gzip 那样使用前导/尾随标识符,但它确实由一系列未压缩的标头和描述压缩数据的命令组成。它们并非都在字节边界上对齐,您必须在位级别解析它们(Brotli 被处理为位和字节流)。有关如何读取这些标头的信息,请参阅第 10 节:解码算法。如果您解析出一些遵循 Brotli 格式的标头而没有错误,那么您正在处理 Brotli 压缩缓冲区是一个不错的选择。

于 2016-08-18T05:59:16.983 回答