如何确定字符串是否被压缩gzcompress
(除了在调用之前/之后比较字符串的大小gzuncompress
,或者这是否是正确的方法)?
问问题
10393 次
3 回答
26
上一篇:
我猜,如果你发送一个请求,你可以立即查看$http_response_header
数组中的一项是否是Content-Encoding: gzip
. 但这是 LAME!
有一个更好的方法。
这是如何...
检查它是否是 GZIP。像一个老板一样!
根据GZIP RFC:
gzip 内容的标头如下所示
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
并将内容标识ID1
为ID2
GZIP。并CM
指出ZLIB_ENCODING
(压缩方法)是ZLIB_ENCODING_DEFLATE
- GZIP 通常将其用于所有 Web 服务器。
哦!并且它们具有固定值:
- ID1的值为
"\x1f"
- ID2的值为
"\x8b"
- CM的值是(或只是 8...)
"\x08"
差不多好了:
$is_gzip = 0 === mb_strpos($mystery_string , "\x1f" . "\x8b" . "\x08");
工作示例
<?php
/** @link https://gist.github.com/eladkarako/d8f3addf4e3be92bae96#file-checking_gzip_like_a_boss-php */
date_default_timezone_set("Asia/Jerusalem");
while (ob_get_level() > 0) ob_end_flush();
mb_language("uni");
@mb_internal_encoding('UTF-8');
setlocale(LC_ALL, 'en_US.UTF-8');
header('Time-Zone: Asia/Jerusalem');
header('Charset: UTF-8');
header('Content-Encoding: UTF-8');
header('Content-Type: text/plain; charset=UTF-8');
header('Access-Control-Allow-Origin: *');
function get($url, $cookie = '') {
$html = @file_get_contents($url, false, stream_context_create([
'http' => [
'method' => "GET",
'header' => implode("\r\n", [''
, 'Pragma: no-cache'
, 'Cache-Control: no-cache'
, 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2310.0 Safari/537.36'
, 'DNT: 1'
, 'Accept-Language: en-US,en;q=0.8'
, 'Accept: text/plain'
, 'X-Forwarded-For: ' . implode(', ', array_unique(array_filter(array_map(function ($item) { return filter_input(INPUT_SERVER, $item, FILTER_SANITIZE_SPECIAL_CHARS); }, ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'HTTP_CLIENT_IP', 'SERVER_ADDR', 'REMOTE_ADDR']), function ($item) { return null !== $item; })))
, 'Referer: http://eladkarako.com'
, 'Connection: close'
, 'Cookie: ' . $cookie
, 'Accept-Encoding: gzip'
])
]]));
$is_gzip = 0 === mb_strpos($html, "\x1f" . "\x8b" . "\x08", 0, "US-ASCII");
return $is_gzip ? zlib_decode($html, ZLIB_ENCODING_DEFLATE) : $html;
}
$html = get('http://www.pogdesign.co.uk/cat/');
echo $html;
我们在这里看到什么值得一提的?
- 首先初始化要使用的 PHP 引擎
UTF-8
(因为我们真的不知道 Web 服务器是否会返回 GZIP 内容。 - 提供 header
Accept-Encoding: gzip
,告诉网络服务器,它可以输出 GZIP 内容。 - 发现 GZIP 内容(您应该使用带有ASCII 编码的多字节函数)。
- 最后返回纯输出,很容易使用这些
ZLIB
方法。
于 2015-03-25T23:59:33.063 回答
9
字符串和压缩字符串都是简单的字节序列。您无法真正区分一个字节序列和另一个字节序列。您应该从随附的元数据中知道字节块是否代表压缩格式。
如果您真的需要以编程方式进行猜测,您可以尝试以下几件事:
- 尝试解压字符串,看看解压操作是否成功。如果失败,则字节可能不代表压缩字符串。
- 尝试像以前一样检查明显的“奇怪”字节
0x20
。这些字节通常不用于常规文本。但是,并不能真正保证它们出现在压缩字符串中。 - 用于
mb_check_encoding
查看字符串在您怀疑它所在的编码中是否有效。如果不是,它可能已被压缩(或者您检查了错误的编码)。需要注意的是,几乎任何字节序列在几乎每个单字节编码中都是有效的,因此这只适用于多字节编码。
于 2012-06-11T07:16:29.597 回答
1
这对我来说很好:
if (@gzuncompress($_xml)!==false) {
// gzipped sring
于 2020-12-17T15:01:33.640 回答