2012-04-03 11 views
7

Después de hacer una solicitud gzip desinflado en PHP, recibo la cadena desinflado en trozos de compensación, que se parece a la siguiente¿Cómo decodificar/inflar una cadena gzip fragmentada?

Ejemplo acortado para mostrar formato:

00001B4E 
¾”kŒj…Øæ’ìÑ«F1ìÊ`+ƒQì¹UÜjùJƒZ\µy¡ÓUžGr‡J&=KLËÙÍ~=ÍkR 
0000102F 
ñÞœÞôΑüo[¾”+’Ñ8#à»0±R-4VÕ’n›êˆÍ.MCŽ…ÏÖr¿3M—èßñ°r¡\+ 
00000000 

no soy capaz de inflar que presumiblemente debido al formato fragmentado. Puedo confirmar que los datos no están corruptos después de eliminar manualmente los desplazamientos con un editor hexadecimal y leer el archivo gzip. Me pregunto si existe un método adecuado para analizar esta respuesta desinflada gzip fragmentada en una cadena legible.

Es posible que pueda dividir estos desplazamientos y unir los datos en una cadena para llamar a gzinflate, pero parece que debe haber una manera más fácil.

Respuesta

9

El método adecuado para desinflar un fragmentada más o menos la respuesta es la siguiente:

initialise string to hold result 
for each chunk { 
    check that the stated chunk length equals the string length of the chunk 
    append the chunk data to the result variable 
} 

Aquí es una función PHP a mano para hacer eso por usted (FIXED):

function unchunk_string ($str) { 

    // A string to hold the result 
    $result = ''; 

    // Split input by CRLF 
    $parts = explode("\r\n", $str); 

    // These vars track the current chunk 
    $chunkLen = 0; 
    $thisChunk = ''; 

    // Loop the data 
    while (($part = array_shift($parts)) !== NULL) { 
    if ($chunkLen) { 
     // Add the data to the string 
     // Don't forget, the data might contain a literal CRLF 
     $thisChunk .= $part."\r\n"; 
     if (strlen($thisChunk) == $chunkLen) { 
     // Chunk is complete 
     $result .= $thisChunk; 
     $chunkLen = 0; 
     $thisChunk = ''; 
     } else if (strlen($thisChunk) == $chunkLen + 2) { 
     // Chunk is complete, remove trailing CRLF 
     $result .= substr($thisChunk, 0, -2); 
     $chunkLen = 0; 
     $thisChunk = ''; 
     } else if (strlen($thisChunk) > $chunkLen) { 
     // Data is malformed 
     return FALSE; 
     } 
    } else { 
     // If we are not in a chunk, get length of the new one 
     if ($part === '') continue; 
     if (!$chunkLen = hexdec($part)) break; 
    } 
    } 

    // Return the decoded data of FALSE if it is incomplete 
    return ($chunkLen) ? FALSE : $result; 

} 
+0

Excelente, funciona tal como se esperaba. Esa es una función útil de PHP, de hecho, he estado buscando esto por un tiempo ahora. ¡Muchas gracias! – user1309276

+0

@ user1309276 He actualizado la función anterior, tenía un error que rodea el comportamiento cuando la cadena contiene un CRLF literal. Esto ahora se ha solucionado, y esto también ha proporcionado una mejor detección de cadenas malformadas. – DaveRandom

+0

¡Gracias de nuevo! Para cualquiera que todavía tenga problemas, después de llamar a unchunk_string todo lo que necesito hacer es eliminar los primeros 10 bytes usando: $ data = gzinflate (substr ($ data, 10)); – user1309276

0

Para decodificar una cadena utilizan gzinflate, Zend_Http_Client lib ayudará a hacer este tipo de tareas comunes, su wasy usar, consulte Zend_Http_Response code si tiene que hacerlo por su propia

+0

Desafortunadamente, ya probé el método que usa lib, pero contiene algún código que podría necesitar en el futuro, ¡gracias! – user1309276

Cuestiones relacionadas