如何确定一个字符串是否用gzcompress压缩过(除了比较调用gzuncompress之前/之后的字符串大小之外,或者这是正确的方法吗)?
gzcompress
gzuncompress
zujrkrfu1#
前:
$http_response_header
Content-Encoding: gzip
有一个更好的方法。以下是如何...
根据GZIP RFC:
+---+---+---+---+---+---+---+---+---+---+ |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) +---+---+---+---+---+---+---+---+---+---+
ID1和ID2将内容标识为GZIP。CM声明**ZLIB_ENCODING**(压缩方法)为ZLIB_ENCODING_DEFLATE-GZIP通常在所有Web服务器上使用此方法。
ID1
ID2
CM
ZLIB_ENCODING
ZLIB_ENCODING_DEFLATE
哦!并且它们具有固定值:ID 1的值为"\x1f"ID 2的值为"\x8b"CM的值为*"\x08"**(或仅为8...)
"\x1f"
"\x8b"
"\x08"
'$is_gzip = 0 === mb_strpos(神秘字符串,“\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;
UTF-8
Accept-Encoding: gzip
ZLIB
sgtfey8w2#
字符串和压缩字符串都是简单的字节序列。你不能真正区分一个字节序列和另一个字节序列。你 * 应该知道 * 字节blob是否代表压缩格式或不伴随元数据。如果您确实需要以编程方式进行 * 猜测 *,您可以尝试以下几种方法:
0x20
mb_check_encoding
dxxyhpgq3#
这对我来说很好:
if (@gzuncompress($_xml)!==false) { // gzipped sring
klsxnrf14#
您可以简单地在@DiDiegodaFonseca标注的数据上尝试gzuncompress(),如果失败,则不是gzcompress()制作的,或者没有如实传输。如果确实需要,可以检查 zlib 头的前两个字节(不是gzip头,因为接受的答案中错误地建议)。gzcompress()生成zlib流,* 不是 * gzip流。gzencode()生成gzip流。gzdeflate()生成原始deflate流。RFC 1950描述了zlib头。它是两个字节,其中作为big-endian 16位无符号整数的两个字节必须是31的倍数。除了检查这一点之外,您还可以检查第一个字节的低四位是否为8(1000),高四位是否为0。
gzuncompress()
gzcompress()
gzencode()
gzdeflate()
4条答案
按热度按时间zujrkrfu1#
前:
$http_response_header
,看看数组中的某个项是否是Content-Encoding: gzip
的变体,但这并不理想!有一个更好的方法。
以下是如何...
* 检查它是否是GZIP。像个老板!*
根据GZIP RFC:
gzip内容的标题如下所示
ID1
和ID2
将内容标识为GZIP。CM
声明**ZLIB_ENCODING
**(压缩方法)为ZLIB_ENCODING_DEFLATE
-GZIP通常在所有Web服务器上使用此方法。哦!并且它们具有固定值:
ID 1的值为
"\x1f"
ID 2的值为
"\x8b"
CM的值为*
"\x08"
**(或仅为8...)就快到了:
'$is_gzip = 0 === mb_strpos(神秘字符串,“\x1f”.“\x8b”.“\x08”);'
工作示例
我们在这里看到了哪些值得一提的内容?
UTF-8
(因为我们不知道Web服务器是否会返回GZIP内容。Accept-Encoding: gzip
,告知web服务器,它可以输出GZIP内容。ZLIB
方法很容易。sgtfey8w2#
字符串和压缩字符串都是简单的字节序列。你不能真正区分一个字节序列和另一个字节序列。你 * 应该知道 * 字节blob是否代表压缩格式或不伴随元数据。
如果您确实需要以编程方式进行 * 猜测 *,您可以尝试以下几种方法:
0x20
之前的任何明显的“奇怪”字节。这些字节通常不会在常规文本中使用。尽管不能真实的保证它们会出现在压缩字符串中。mb_check_encoding
查看一个字符串在你怀疑的编码中是否有效。如果不是,它可能被压缩了(或者你检查了错误的编码)。需要注意的是,实际上任何字节序列在每一个单字节编码中都是有效的,所以这只适用于多字节编码。dxxyhpgq3#
这对我来说很好:
klsxnrf14#
您可以简单地在@DiDiegodaFonseca标注的数据上尝试
gzuncompress()
,如果失败,则不是gzcompress()
制作的,或者没有如实传输。如果确实需要,可以检查 zlib 头的前两个字节(不是gzip头,因为接受的答案中错误地建议)。
gzcompress()
生成zlib流,* 不是 * gzip流。gzencode()
生成gzip流。gzdeflate()
生成原始deflate流。RFC 1950描述了zlib头。它是两个字节,其中作为big-endian 16位无符号整数的两个字节必须是31的倍数。除了检查这一点之外,您还可以检查第一个字节的低四位是否为8(1000),高四位是否为0。