如何确定字符串是否被压缩?

Max*_*Max 8 php compression string

如何判断字符串是否被压缩gzcompress(gzuncompress除了在调用之前/之后比较字符串的大小,还是正确的方式)?

小智 22

PRE:
我想,如果您发送请求,您可以立即查看$http_response_header数组中的某个项是否是变体Content-Encoding: gzip.但这是LAME!
有一个更好的方法.


这是如何......

检查是否有GZIP.像一个老板一样!

根据GZIP RFC:

gzip内容的标题如下所示

+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)

ID1ID2 标识内容为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;
Run Code Online (Sandbox Code Playgroud)

我们在这里看到什么值得一提的?

  • 首先要初始化要使用的PHP引擎UTF-8(因为我们不知道Web服务器是否会返回GZIP内容.
  • 提供标题Accept-Encoding: gzip,告诉web服务器,它可以输出GZIP内容.
  • 发现GZIP内容(您应该使用ASCII编码的多字节函数).
  • 最后返回普通输出,很容易使用这些ZLIB方法.

  • 适用于[gzencode](http://php.net/gzencode)d字符串,但不适用于[gzcompress](http://php.net/manual/en/function.gzcompress.php)ed字符串,没有gzip-header,所以我这样做:`function isGzipped($ in){if(mb_strpos($ in,"\ x1f"."\ x8b"."\ x08")=== 0){return true ; } else if(@gzuncompress($ in)!== false){return true; } else {return false; } (6认同)

dec*_*eze 8

字符串和压缩字符串都是简单的字节序列.您无法将一个字节序列与另一个字节序列区分开来.您应该知道一小块字节是否表示来自附带元数据的压缩格式.

如果你真的需要以编程方式猜测,你可以尝试几件事:

  • 尝试解压缩字符串并查看解压缩操作是否成功.如果失败,则字节可能不代表压缩字符串.
  • 尝试检查明显的"怪异"字节,就像以前一样0x20.这些字节通常不用于常规文本.但是没有真正保证它们出现在压缩字符串中.
  • mb_check_encoding看一个字符串是否是在你怀疑它是在编码有效.如果不是,它可能压缩(或者你检查了错误的编码).需要注意的是,几乎所有字节序列在几乎每个单字节编码中都是有效的,所以这只适用于多字节编码.

  • 请注意,“\t”(制表符)、“\n”(换行符)和“\r”(回车)都可能出现在任何字符串中,并且都低于 0x20。 (2认同)