10

文字列が圧縮されているかどうかを判断するにはどうすればよいですかgzcompress(を呼び出す前後の文字列のサイズを比較することは別gzuncompressとして、またはそれが適切な方法でしょうか) ?

4

3 に答える 3

26

前:リクエスト
を送信すると、配列内のアイテムの 1 つが のバリエーションであるかどうかをすぐに調べることができると思います。しかし、これはラメです! はるかに優れた方法があります。$http_response_headerContent-Encoding: gzip


方法は次のとおりです...

そのGZIPかどうかを確認してください。偉ぶって!

GZIP RFCによると:

gzip コンテンツのヘッダーは次のようになります

+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+

ID1およびID2 コンテンツを GZIP として識別します。そして、 (圧縮方法)は- であるとCM述べています-これは、すべてのWebサーバーでGZIPによって慣習的に使用されています。ZLIB_ENCODINGZLIB_ENCODING_DEFLATE

おー!そしてそれらは固定値を持っています:

  • 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 エンジンを初期化することから始めます(Web サーバーGZIP コンテンツを返すUTF-8かどうかはわからないためです。
  • headerAccept-Encoding: gzipを指定すると、Web サーバーに、GZIP コンテンツを出力する可能性があることが通知されます。
  • GZIP コンテンツの検出 (マルチバイト関数をASCII エンコーディングで使用する必要があります)。
  • 最後にプレーンな出力を返すのは、ZLIBメソッドを使用して簡単です。
于 2015-03-25T23:59:33.063 に答える
9

文字列と圧縮された文字列はどちらも単純なバイト シーケンスです。あるバイト シーケンスと別のバイト シーケンスを実際に区別することはできません。付随するメタデータから、バイトのブロブが圧縮形式を表しているかどうかを知る必要があります。

本当にプログラムで推測する必要がある場合は、いくつか試してみることができます。

  • 文字列を解凍して、解凍操作が成功するかどうかを確認してください。失敗した場合、バイトは圧縮された文字列を表していない可能性があります。
  • 以前のように、明らかな「奇妙な」バイトをチェックしてみてください0x20。これらのバイトは通常、通常のテキストでは使用されません。ただし、それらが圧縮された文字列で発生するという実際の保証はありません。
  • 疑わしいエンコーディングで文字列が有効かどうかを確認するために使用mb_check_encodingします。そうでない場合は、圧縮されている可能性があります (または、間違ったエンコーディングを確認しました)。事実上すべてのバイト シーケンスが事実上すべてのシングル バイト エンコーディングで有効であるという警告があるため、これはマルチバイト エンコーディングでのみ機能します。
于 2012-06-11T07:16:29.597 に答える