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

时间:2016-08-18 02:17:42

标签: c++ compression brotli

我是一名实习生正在研究在一个软件中使用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压缩而不尝试解压缩并等待失败?

2 个答案:

答案 0 :(得分:4)

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

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

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

简而言之,误报的概率相对较高,而查找负数的字节数可能非常大。

如果您正在编写此软件,那么您应该在brotli数据之前放置自己的标题以帮助检测。或者您可以使用brotli framing format that I developed at their request,它在brotli压缩流之前具有唯一的四字节标头。这将大大降低误报的可能性。

答案 1 :(得分:1)

Brotli在RFC 7932中正式定义。 Section 2: Compressed Representation OverviewSection 9: Compressed Data Format涵盖了数据流的格式。 Brotli不使用像gzip那样的前导/尾随标识符,但它确实包含一系列未压缩的头文件和描述压缩数据的命令。它们并非全部在字节边界上对齐,您必须在位级别解析它们(Brotli被处理为位和字节流)。有关如何阅读这些标题,请参阅Section 10: Decoding Algorithm。如果您解析出几个没有错误的Brotli格式的标题,那么您可以选择使用Brotli压缩缓冲区。