有没有一种方法可以测试一个字符串是否被gz压缩?

9

也就是说,我要测试是否能够安全地对字符串进行gzinflate。

如果我的压缩数据被篡改了,我会收到一个“坏数据”警告。我不想抑制这个警告,这意味着我要么必须捕获它,要么测试它是否可以被gzinflate。后者是我的首选解决方案,但我不知道该如何实现。

以下代码示例应该能帮助你:

if(i_can_haz_inflate($data))
{
    // go ahead
    $source = gzinflate($data);
}
else
{
    // bad data
}

编辑:我已经指定了gz(de | in)flate,意识到我实际上并不太关心压缩算法。是否有更适合在尝试解压缩之前检查完整性的算法?


1
Deflate不会加入魔术字节来显示其编码方式,因为这意味着结果会占用更多的空间。唯一实现这一目的的方法是尝试并查看是否出现问题。 - Tom van der Woerdt
1
话虽如此:实际上,deflate 的一个缺陷导致它在篡改时失败。完美的压缩算法将允许任何数据作为输入。 - Tom van der Woerdt
2个回答

7

gzinflate()函数会在原字符串不是gzdeflate()编码字符串时返回原字符串。

最显然的检查方法是:

$deflated = @gzinflate($data); // to avoid getting a warning
if ($data != $deflated && $deflated !== FALSE) {
     $source  = gzinflate($data);
}

我认为没有其他方法可以做到这一点。

1
这种方法可能仍然是最佳途径。我知道这不是 PHP 风格,只是试图先问问题(实际上这是 Python 风格),但这仍然是最佳途径。 - Tom van der Woerdt
我同意你的看法,Gordon,但我认为没有其他方法可以做到。 - Vlad Preda
那段代码可以通过仅调用一次gzinflate()来提高效率。但前两个调用需要使用抑制器(@)修饰符,而我真的很不想使用它。也许这只是最好的选择。 - Matt
gzinflate() 在出现错误的情况下返回原始数据是关键所在,谢谢。 - Matt
似乎这是一个变通方法,因为你仍然需要消除警告。很遗憾这种情况没有被预料到。 - COil
显示剩余3条评论

2

我同意 @Vlad Preda 答案,但我们可以将警告转换为异常:

set_error_handler(function ($code, $description) {
    throw new \RuntimeException($description, $code);
});
$deflated = gzinflate($data);
restore_error_handler();

它为我们提供了处理异常的能力...并且不会抑制警告...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接