3 votes

Comment fonctionne gzcompress?

Je me demande pourquoi je dois couper les 4 derniers caractères, après avoir utilisé gzcompress().

Voici mon code :

header("Content-Encoding: gzip");
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$index = $smarty->fetch("design/templates/main.htm") ."\n";
$this->content_size = strlen($index);
$this->content_crc = crc32($index);
$index = gzcompress($index, 9);
$index = substr($index, 0, strlen($index) - 4); // Pourquoi couper ??
echo $index;
echo pack('V', $this->content_crc) . pack('V', $this->content_size);

Lorsque je ne coupe pas les 4 derniers caractères, la source se termine comme suit :

[...]
N

Lorsque je les coupe, cela se lit :

[...]

J'ai pu voir le N supplémentaire uniquement dans l'inspecteur de code de Chrome (pas dans Firefox et pas dans la source de IE). Mais il semble y avoir quatre caractères supplémentaires à la fin du code.

Est-ce que quelqu'un peut m'expliquer pourquoi je dois couper 4 caractères ?

8voto

Gumbo Points 279147

gzcompress implémente le format de données compressées ZLIB qui a la structure suivante:

     0   1
   +---+---+
   |CMF|FLG|   (suite-->)
   +---+---+

(si FLG.FDICT est défini)

     0   1   2   3
   +---+---+---+---+
   |     DICTID    |   (suite-->)
   +---+---+---+---+

   +=====================+---+---+---+---+
   |...données compressées...|    ADLER32    |
   +=====================+---+---+---+---+

Ici vous voyez que les quatre derniers octets sont un checksum Adler-32.

Par contraste, le format de fichier GZIP est une liste de membres avec la structure suivante:

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

(si FLG.FEXTRA est défini)

   +---+---+=================================+
   | XLEN  |...XLEN bytes du "champ supplémentaire"...| (suite-->)
   +---+---+=================================+

(si FLG.FNAME est défini)

   +=========================================+
   |...nom de fichier d'origine, terminé par zéro...| (suite-->)
   +=========================================+

(si FLG.FCOMMENT est défini)

   +===================================+
   |...commentaire de fichier, terminé par zéro...| (suite-->)
   +===================================+

(si FLG.FHCRC est défini)

   +---+---+
   | CRC16 |
   +---+---+

   +=======================+
   |...blocs compressés...| (suite-->)
   +=======================+

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   |     CRC32     |     ISIZE     |
   +---+---+---+---+---+---+---+---+

Comme vous pouvez le voir, GZIP utilise un checksum CRC-32 pour la vérification de l'intégrité.

Donc pour analyser votre code:

  • echo "\x1f\x8b\x08\x00\x00\x00\x00\x00"; – affiche les champs d'en-tête suivants:
    • 0x1f 0x8b – ID1 et ID2, identifiants pour identifier le format de données (ces valeurs sont fixes)
    • 0x08 – CM, méthode de compression utilisée ; 8 indique l'utilisation du format de compression de données DEFLATE (RFC 1951)
    • 0x00 – FLG, drapeaux
    • 0x00000000 – MTIME, heure de modification
    • les champs XFL (drapeaux supplémentaires) et OS (système d'opération) sont définis par le format de compression de données DEFLATE
  • echo $index; – affiche les données compressées selon le format de compression de données DEFLATE
  • echo pack('V', $this->content_crc) . pack('V', $this->content_size); – affiche le checksum CRC-32 et la taille des données d'entrée non compressées en binaire

2voto

nos Points 102226

Gzcompress produit une sortie décrite ici RFC1950, les 4 derniers octets que vous supprimez sont le checksum adler32. Il s'agit du codage "déflation", vous devez donc simplement définir "Content-Encoding: deflate" et ne rien manipuler d'autre.

Si vous voulez utiliser gzip, utilisez gzencode(), qui utilise le format gzip.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X