рдЬрд╝рд┐рдк рдЖрд░реНрдХрд╛рдЗрд╡ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рднрд╛рдЧ 2 - рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдФрд░ рд╕рдВрдкреАрдбрд╝рди

рд▓реЗрдЦ рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рдЬрд╝рд┐рдк рд╕рдВрдЧреНрд░рд╣ рдХреИрд╕реЗ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред


рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛


рд╢реБрдн рджрд┐рдиред
рдФрд░ рдлрд┐рд░ рд╕реЗ рд╣рд╡рд╛ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ PHP рдореЗрдВ рдЕрдкрд░рдВрдкрд░рд╛рдЧрдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╣реИред


рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рд╕рдореНрдорд╛рдирд┐рдд рдкрд╛рдардХреЛрдВ рдХреЛ рдЬрд┐рдк рд╕рдВрдкреАрдбрд╝рди рдФрд░ рдЬрд┐рдк рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдореЗрдВ рд░реБрдЪрд┐ рдереАред рдЖрдЬ рд╣рдо рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рдереЛрдбрд╝рд╛ рдЦреЛрд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗред


рдЖрдЗрдП рдПрдХ рдирдЬрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ

рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рдХреЛрдб
<?php //        (1.txt  2.txt)   : $entries = [ '1.txt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc id ante ultrices, fermentum nibh eleifend, ullamcorper nunc. Sed dignissim ut odio et imperdiet. Nunc id felis et ligula viverra blandit a sit amet magna. Vestibulum facilisis venenatis enim sed bibendum. Duis maximus felis in suscipit bibendum. Mauris suscipit turpis eleifend nibh commodo imperdiet. Donec tincidunt porta interdum. Aenean interdum condimentum ligula, vitae ornare lorem auctor in. Suspendisse metus ipsum, porttitor et sapien id, fringilla aliquam nibh. Curabitur sem lacus, ultrices quis felis sed, blandit commodo metus. Duis tincidunt vel mauris at accumsan. Integer et ipsum fermentum leo viverra blandit.', '2.txt' => 'Mauris in purus sit amet ante tempor finibus nec sed justo. Integer ac nibh tempus, mollis sem vel, consequat diam. Pellentesque ut condimentum ex. Praesent finibus volutpat gravida. Vivamus eleifend neque sit amet diam scelerisque lacinia. Nunc imperdiet augue in suscipit lacinia. Curabitur orci diam, iaculis non ligula vitae, porta pellentesque est. Duis dolor erat, placerat a lacus eu, scelerisque egestas massa. Aliquam molestie pulvinar faucibus. Quisque consequat, dolor mattis lacinia pretium, eros eros tempor neque, volutpat consectetur elit elit non diam. In faucibus nulla justo, non dignissim erat maximus consectetur. Sed porttitor turpis nisl, elementum aliquam dui tincidunt nec. Nunc eu enim at nibh molestie porta ut ac erat. Sed tortor sem, mollis eget sodales vel, faucibus in dolor.', ]; //      Lorem.zip,      cwd (      ) $destination = 'Lorem.zip'; $handle = fopen($destination, 'w'); //      ,    ,     ,   "" Central Directory File Header $written = 0; $dictionary = []; foreach ($entries as $filename => $content) { //         Local File Header,     //        ,      . $fileInfo = [ //     'versionToExtract' => 10, //   0,        - 'generalPurposeBitFlag' => 0, //      ,    0 'compressionMethod' => 0, // -    mtime ,    ,      ? 'modificationTime' => 28021, //   , ? 'modificationDate' => 20072, //      .     ,       ,   ? 'crc32' => hexdec(hash('crc32b', $content)), //     .        . //       :) 'compressedSize' => $size = strlen($content), 'uncompressedSize' => $size, //    'filenameLength' => strlen($filename), //  .    ,   0. 'extraFieldLength' => 0, ]; //      . $LFH = pack('LSSSSSLLLSSa*', ...array_values([ 'signature' => 0x04034b50, //  Local File Header ] + $fileInfo + ['filename' => $filename])); //       ,       Central Directory File Header $dictionary[$filename] = [ 'signature' => 0x02014b50, //  Central Directory File Header 'versionMadeBy' => 798, //  .    ,  -  . ] + $fileInfo + [ 'fileCommentLength' => 0, //    . No comments 'diskNumber' => 0, //     0,        'internalFileAttributes' => 0, //    'externalFileAttributes' => 2176057344, //    'localFileHeaderOffset' => $written, //      Local File Header 'filename' => $filename, //  . ]; //      $written += fwrite($handle, $LFH); //    $written += fwrite($handle, $content); } // ,     ,    . //          End of central directory record (EOCD) $EOCD = [ //  EOCD 'signature' => 0x06054b50, //  .    ,   0 'diskNumber' => 0, //      -  0 'startDiskNumber' => 0, //       . 'numberCentralDirectoryRecord' => $records = count($dictionary), //    .    ,     'totalCentralDirectoryRecord' => $records, //   Central Directory Record. //      ,      'sizeOfCentralDirectory' => 0, // ,    Central Directory Records 'centralDirectoryOffset' => $written, //     'commentLength' => 0 ]; //     !   foreach ($dictionary as $entryInfo) { $CDFH = pack('LSSSSSSLLLSSSSSLLa*', ...array_values($entryInfo)); $written += fwrite($handle, $CDFH); } // ,   .  ,    $EOCD['sizeOfCentralDirectory'] = $written - $EOCD['centralDirectoryOffset']; //     End of central directory record $EOCD = pack('LSSSSLLS', ...array_values($EOCD)); $written += fwrite($handle, $EOCD); //  . fclose($handle); echo '  : ' . $written . ' ' . PHP_EOL; echo '     `unzip -tq ' . $destination . '`' . PHP_EOL; echo PHP_EOL; 


рдЙрд╕рдХреА рд╕рдорд╕реНрдпрд╛ рдХреНрдпрд╛ рд╣реИ? рдЦреИрд░, рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ рдореЗрдВ, рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдлрд╛рдпрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╡рд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреАред

рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдкрд╣рд▓реЗ crc32 рдФрд░ рдлрд╝рд╛рдЗрд▓ рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рд╕реНрдерд╛рдиреАрдп рдлрд╝рд╛рдЗрд▓ рд╣реИрдбрд░ (LFH) рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдлрд┐рд░ рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╣реАред
рдЗрд╕рд╕реЗ рдХреНрдпрд╛ рдЦрддрд░рд╛ рд╣реИ? рдпрд╛ рд╣рдо рдкреВрд░реА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП crc32 рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, LFH рд▓рд┐рдЦреЗрдВ, рдФрд░ рдлрд┐рд░ рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА I / O рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдХрд┐рдлрд╛рдпрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдмрдбрд╝реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрд╡реАрдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИред рдпрд╛ рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреЛ 2 рдмрд╛рд░ рдкрдврд╝рддреЗ рд╣реИрдВ - рдкрд╣рд▓реЗ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рдлрд┐рд░ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкрдврд╝рдиреЗ рдФрд░ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП - рдЖрд░реНрдерд┐рдХ рд░реВрдк рд╕реЗ рд░рд╛рдо рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рд▓реЗрдХрд┐рди, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдпрд╣ рдбреНрд░рд╛рдЗрд╡ рдкрд░ рд▓реЛрдб рдХреЛ рджреЛрдЧреБрдирд╛ рдХрд░ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдПрдХ рдПрд╕рдПрд╕рдбреА рд╣реИред

рдФрд░ рдЕрдЧрд░ рдлрд╝рд╛рдЗрд▓ рджреВрд░рд╕реНрде рд░реВрдк рд╕реЗ рд╕реНрдерд┐рдд рд╣реИ рдФрд░ рдЗрд╕рдХреА рдорд╛рддреНрд░рд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 1.5GB? рдЦреИрд░, рдЖрдкрдХреЛ рдпрд╛ рддреЛ рд╕рднреА 1.5GB рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдпрд╛ рдЗрди рд╕рднреА 1.5GB рдХреЗ рдбрд╛рдЙрдирд▓реЛрдб рд╣реЛрдиреЗ рддрдХ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рд╣рдо рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдордЧреНрд░реА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВрдЧреЗред рдпрджрд┐ рд╣рдо рдордХреНрдЦреА рдкрд░ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдбрдВрдк рдбреЗрдЯрд╛рдмреЗрд╕, рдЬрд┐рд╕реЗ рд╣рдо, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдЯрдбрдЖрдЙрдЯ рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЖрдо рддреМрд░ рдкрд░ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ - рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдбреЗрдЯрд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рдбрдВрдк рдбреЗрдЯрд╛ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛, рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ-рдерд▓рдЧ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдПрдХ рдЕрдорд╛рдиреНрдп рд╕рдВрдЧреНрд░рд╣ рдорд┐рд▓реЗрдЧрд╛ред рд╣рд╛рдБ, рдЪреАрдЬреЗрдВ рдЦрд░рд╛рдм рд╣реИрдВ, рдмрд┐рд▓реНрдХреБрд▓ред


рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдЕрднрд┐рд▓реЗрдЦ рдЕрднрд┐рд▓реЗрдЦреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рд╕рдВрд░рдЪрдирд╛


рд▓реЗрдХрд┐рди рд╣рддреЛрддреНрд╕рд╛рд╣рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд╝рд┐рдк рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рдж рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ (рдбреАрдбреА) рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЪрд┐рдкрдХрд╛ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА crc32, рдкреИрдХреНрдб рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рдФрд░ рдмрд┐рдирд╛ рд╕рдВрдкреАрдбрд╝рди рдХреЗ рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рд╣реЛрдЧреАред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ LFH рдореЗрдВ рдПрдХ рдЦрд╛рд▓реА рдкреЗрдЯ рдкрд░ рджрд┐рди рдореЗрдВ рдХреЗрд╡рд▓ 3 рдмрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, 0P0008 рдХреЗ рдмрд░рд╛рдмрд░ generalPurposeBitFlag рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ, рдФрд░ crc32 , рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░реЗрдВ рдФрд░ 0 рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВред рдлрд┐рд░, рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рдж, рд╣рдо DD рд╕рдВрд░рдЪрдирд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЬреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:



 pack('LLLL', ...array_values([ 'signature' => 0x08074b50, //  Data Descriptor 'crc32' => $crc32, //  crc32    'compressedSize' => $compressedSize, //    'uncompressedSize' => $uncompressedSize, //    . ])); 

рдФрд░ рд╕реЗрдВрдЯреНрд░рд▓ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдлрд╛рдЗрд▓ рд╣реИрдбрд░ (рд╕реАрдбреАрдПрдлрдПрдЪ) рдореЗрдВ рдХреЗрд╡рд▓ рд╕рд╛рдорд╛рдиреНрдпрдкрд╛рд░реНрдЯрдмрд┐рдЯрдмреНрд▓реИрдл рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ , рдмрд╛рдХреА рдбреЗрдЯрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╕рднреА рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рдж рд╕реАрдбреАрдПрдлрдПрдЪ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдбреЗрдЯрд╛ рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рд╣реИрд╢ рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред


рдпрд╣ рд╕рдм, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЕрдЪреНрдЫрд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ PHP рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред
рдФрд░ рдорд╛рдирдХ рд╣реИрд╢ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд╣рдореЗрдВ рдмрд╣реБрдд рдорджрдж рдорд┐рд▓реЗрдЧреАред рд╣рдо рдПрдХ рд╣реИрд╢ рд╕рдВрджрд░реНрдн рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рдЦрдВрдбреВ рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛, рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣реИрд╢ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдмреЗрд╢рдХ, рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╣реИрд╢ ('crc32b', $ рд╕рд╛рдордЧреНрд░реА) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреБрдЫ рдЕрдзрд┐рдХ рдмреЛрдЭрд┐рд▓ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдореЗрдВ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдФрд░ рд╕рдордп рдХреЗ рдПрдХ рдЕрдХрд▓реНрдкрдиреАрдп рдЧреБрдЪреНрдЫрд╛ рд╕реЗ рдмрдЪрд╛рдПрдЧрд╛ред

рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 $hashCtx = hash_init('crc32b'); $handle = fopen($source, 'r'); while (!feof($handle)) { $chunk = fread($handle, 8 * 1024); hash_update($hashCtx, $chunk); $chunk = null; } $hash = hash_final($hashCtx); 

рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдорд╛рди hash_file ('crc32b', $ source) рдпрд╛ hash ('crc32b', file_get_content ($ source)) рд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

рдЖрдЗрдП рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЗрд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рддрд╛рдХрд┐ рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрдврд╝ рд╕рдХреЗрдВ, рдФрд░ рдЕрдВрдд рдореЗрдВ рдЗрд╕рдХреА рд╣реИрд╢ рдФрд░ рд▓рдВрдмрд╛рдИ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХреЗрдВред рдФрд░ рдЬрдирд░реЗрдЯрд░ рд╣рдореЗрдВ рдЗрд╕рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗ:

 function read(string $path): \Generator { $length = 0; $handle = fopen($path, 'r'); $hashCtx = hash_init('crc32b'); while (!feof($handle)) { $chunk = fread($handle, 8 * 1024); $length += strlen($chunk); hash_update($hashCtx, $chunk); yield $chunk; $chunk = null; } fclose($handle); return ['length' => $length, 'crc32' => hexdec(hash_final($hashCtx))]; } 

рдФрд░ рдЕрдм рд╣рдо рдмрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

 $reader = read('https://speed.hetzner.de/1GB.bin'); foreach ($reader as $chunk) { // -   . } //      . ['length' => $length, 'crc32' => $crc32] = $reader->getReturn(); echo round(memory_get_peak_usage(true) / 1024 / 1024, 2) . 'MB - Memory Peak Usage' . PHP_EOL; 

рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред 1GB рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде, рдореЗрд░реА рдЪрд░рдо рдореЗрдореЛрд░реА рдЦрдкрдд 2MB рдереАред

рдЕрдм рд╣рдо рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВред

рдЕрдВрддрд┐рдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ
 <?php function read(string $path): \Generator { $length = 0; $handle = fopen($path, 'r'); $hashCtx = hash_init('crc32b'); while (!feof($handle)) { $chunk = fread($handle, 8 * 1024); $length += strlen($chunk); hash_update($hashCtx, $chunk); yield $chunk; $chunk = null; } fclose($handle); return ['length' => $length, 'crc32' => hexdec(hash_final($hashCtx))]; } $entries = ['https://speed.hetzner.de/100MB.bin', __FILE__]; $destination = 'test.zip'; $handle = fopen($destination, 'w'); $written = 0; $dictionary = []; foreach ($entries as $entry) { $filename = basename($entry); $fileInfo = [ 'versionToExtract' => 10, //       Data Descriptor,     00008, //   00000    . 'generalPurposeBitFlag' => 0x0008, 'compressionMethod' => 0, 'modificationTime' => 28021, 'modificationDate' => 20072, 'crc32' => 0, 'compressedSize' => 0, 'uncompressedSize' => 0, 'filenameLength' => strlen($filename), 'extraFieldLength' => 0, ]; $LFH = pack('LSSSSSLLLSSa*', ...array_values([ 'signature' => 0x04034b50, ] + $fileInfo + ['filename' => $filename])); $fileOffset = $written; $written += fwrite($handle, $LFH); //     $reader = read($entry); foreach ($reader as $chunk) { //      $written += fwrite($handle, $chunk); $chunk = null; } //       ['length' => $length, 'crc32' => $crc32] = $reader->getReturn(); //    fileInfo,     CDFH $fileInfo['crc32'] = $crc32; $fileInfo['compressedSize'] = $length; $fileInfo['uncompressedSize'] = $length; //  Data Descriptor $DD = pack('LLLL', ...array_values([ 'signature' => 0x08074b50, 'crc32' => $fileInfo['crc32'], 'compressedSize' => $fileInfo['compressedSize'], 'uncompressedSize' => $fileInfo['uncompressedSize'], ])); $written += fwrite($handle, $DD); $dictionary[$filename] = [ 'signature' => 0x02014b50, 'versionMadeBy' => 798, ] + $fileInfo + [ 'fileCommentLength' => 0, 'diskNumber' => 0, 'internalFileAttributes' => 0, 'externalFileAttributes' => 2176057344, 'localFileHeaderOffset' => $fileOffset, 'filename' => $filename, ]; } $EOCD = [ 'signature' => 0x06054b50, 'diskNumber' => 0, 'startDiskNumber' => 0, 'numberCentralDirectoryRecord' => $records = count($dictionary), 'totalCentralDirectoryRecord' => $records, 'sizeOfCentralDirectory' => 0, 'centralDirectoryOffset' => $written, 'commentLength' => 0 ]; foreach ($dictionary as $entryInfo) { $CDFH = pack('LSSSSSSLLLSSSSSLLa*', ...array_values($entryInfo)); $written += fwrite($handle, $CDFH); } $EOCD['sizeOfCentralDirectory'] = $written - $EOCD['centralDirectoryOffset']; $EOCD = pack('LSSSSLLS', ...array_values($EOCD)); $written += fwrite($handle, $EOCD); fclose($handle); echo '  : ' . memory_get_peak_usage(true) . ' ' . PHP_EOL; echo '  : ' . $written . ' ' . PHP_EOL; echo '   `unzip -tq ' . $destination . '`: ' . PHP_EOL; echo '> ' . exec('unzip -tq ' . $destination) . PHP_EOL; echo PHP_EOL; 


рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ, рд╣рдореЗрдВ рдирд╛рдо test.zip рдХреЗ рд╕рд╛рде рдПрдХ рдЬрд╝рд┐рдк рд╕рдВрдЧреНрд░рд╣ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ 100 рдПрдордмреА.рдмрд┐рди рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╣реЛрдЧреА, рдЖрдХрд╛рд░ рдореЗрдВ рд▓рдЧрднрдЧ 100 рдПрдордмреАред

рдЬрд╝рд┐рдк рдЕрднрд┐рд▓реЗрдЦрд╛рдЧрд╛рд░ рдореЗрдВ рд╕рдВрдкреАрдбрд╝рди


рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧрднрдЧ рд╕рдм рдХреБрдЫ рд╣реИ рдФрд░ рдпрд╣ рдордХреНрдЦреА рдкрд░ рднреА рд╣реИред
рдЬрд┐рд╕ рддрд░рд╣ рд╣рдореЗрдВ рдлрдВрдХреНрд╢рдиреНрд╕ рдХреЗ рд▓рд┐рдП рдЫреЛрдЯреЗ-рдЫреЛрдЯреЗ рд╡рд┐рд░рд╛рдо рджреЗрдиреЗ рд╕реЗ рдПрдХ рд╣реИрд╢ рдорд┐рд▓рддрд╛ рд╣реИ, рдЙрд╕реА рддрд░рд╣ рд╣рдо рдбреЗрдЯрд╛ рдХреЛ рд▓рд╛рдЬрд╡рд╛рдм рдЬрд╝реНрд▓рд┐рдм рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдФрд░ рдЙрд╕рдХреЗ рдбрд┐рдлреНрд▓реЗрдЯ_рдЗрдирд┐рдЯ рдФрд░ рдбрд┐рдлреНрд▓реЗрдЯ_рдПрдб рдХреЗ рдлрдВрдХреНрд╢рдиреНрд╕ рд╕реЗ рднреА рдХрдВрдкреНрд░реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 $deflateCtx = deflate_init(ZLIB_ENCODING_RAW, ['level' => 6]); $handle = fopen($source, 'r'); while (!feof($handle)) { $chunk = fread($handle, 8 * 1024); yield deflate_add($deflateCtx, $chunk, feof($handle) ? ZLIB_FINISH : ZLIB_SYNC_FLUSH); $chunk = null; } 

рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдорд┐рд▓рд╛, рдЬреЛ рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рд╢реВрдиреНрдп рдЬреЛрдбрд╝ рджреЗрдЧрд╛ред
рд╕реНрдкрд╛рдпрд▓рд░ рд╣реЗрдбрд┐рдВрдЧ
 while (!feof($handle)) { yield deflate_add($deflateCtx, $chunk, ZLIB_SYNC_FLUSH); } yield deflate_add($deflateCtx, '', ZLIB_FINISH); 

рд▓реЗрдХрд┐рди рдЕрдирдЭрд┐рдк рдХрд╕рдо, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рд░рд▓реАрдХрд░рдг рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдирд╛ рдерд╛ред

рдЖрдЗрдП рд╣рдорд╛рд░реЗ рдкрд╛рдардХ рдХреЛ рдареАрдХ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рддреБрд░рдВрдд рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░реЗ, рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣рдореЗрдВ рдПрдХ рд╣реИрд╢ рджреЗрддрд╛ рд╣реИ, рдмрд┐рдирд╛ рд╕рдВрдкреАрдбрд╝рди рдХреЗ рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рдФрд░ рд╕рдВрдкреАрдбрд╝рди рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ:

 function read(string $path): \Generator { $uncompressedSize = 0; $compressedSize = 0; $hashCtx = hash_init('crc32b'); $deflateCtx = deflate_init(ZLIB_ENCODING_RAW, ['level' => 6]); $handle = fopen($path, 'r'); while (!feof($handle)) { $chunk = fread($handle, 8 * 1024); hash_update($hashCtx, $chunk); $compressedChunk = deflate_add($deflateCtx, $chunk, feof($handle) ? ZLIB_FINISH : ZLIB_SYNC_FLUSH); $uncompressedSize += strlen($chunk); $compressedSize += strlen($compressedChunk); yield $compressedChunk; $chunk = null; $compressedChunk = null; } fclose($handle); return [ 'uncompressedSize' => $uncompressedSize, 'compressedSize' => $compressedSize, 'crc32' => hexdec(hash_final($hashCtx)) ]; } 

рдФрд░ 100 mb рдлрд╝рд╛рдЗрд▓ рдкрд░ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

 $reader = read('https://speed.hetzner.de/100MB.bin'); foreach ($reader as $chunk) { // -   . } ['uncompressedSize' => $uncompressedSize, 'compressedSize' => $compressedSize, 'crc32' => $crc32] = $reader->getReturn(); echo 'Uncompressed size: ' . $uncompressedSize . PHP_EOL; echo 'Compressed size: ' . $compressedSize . PHP_EOL; echo round(memory_get_peak_usage(true) / 1024 / 1024, 2) . 'MB - Memory Peak Usage' . PHP_EOL; 

рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдЕрднреА рднреА рдмрддрд╛рддреА рд╣реИ рдХрд┐ рд╣рдордиреЗ рдкреВрд░реА рдлрд╛рдЗрд▓ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдирд╣реАрдВ рдХрд┐рдпрд╛ред

рдЖрдЗрдП рдЗрд╕реЗ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦреЗрдВ рдФрд░ рдЕрдВрдд рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдВрдЧреНрд░рд╣ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╣рдорд╛рд░рд╛ рд╕рд╛рдорд╛рдиреНрдпрдкреНрд░рд╛рдердкрд┐рдЯрдмрд┐рдЯрдлрд▓ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ - рдЕрдм рдЗрд╕рдХрд╛ рдореВрд▓реНрдп 0x0018 рд╣реИ , рд╕рд╛рде рд╣реА рд╕рд╛рде рдХрдореНрдкреНрд░реЗрд╢рдирдореЗрдереЛрдб - 8 (рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдбрд┐рдлреНрд▓реИрдЯ )ред

рдЕрдВрддрд┐рдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ
 <?php function read(string $path): \Generator { $uncompressedSize = 0; $compressedSize = 0; $hashCtx = hash_init('crc32b'); $deflateCtx = deflate_init(ZLIB_ENCODING_RAW, ['level' => 6]); $handle = fopen($path, 'r'); while (!feof($handle)) { $chunk = fread($handle, 8 * 1024); hash_update($hashCtx, $chunk); $compressedChunk = deflate_add($deflateCtx, $chunk, feof($handle) ? ZLIB_FINISH : ZLIB_SYNC_FLUSH); $uncompressedSize += strlen($chunk); $compressedSize += strlen($compressedChunk); yield $compressedChunk; $chunk = null; $compressedChunk = null; } fclose($handle); return [ 'uncompressedSize' => $uncompressedSize, 'compressedSize' => $compressedSize, 'crc32' => hexdec(hash_final($hashCtx)) ]; } $entries = ['https://speed.hetzner.de/100MB.bin', __FILE__]; $destination = 'test.zip'; $handle = fopen($destination, 'w'); $written = 0; $dictionary = []; foreach ($entries as $entry) { $filename = basename($entry); $fileInfo = [ 'versionToExtract' => 10, //   ,        0x0018  0x0008 'generalPurposeBitFlag' => 0x0018, 'compressionMethod' => 8, //      : 8 - Deflate 'modificationTime' => 28021, 'modificationDate' => 20072, 'crc32' => 0, 'compressedSize' => 0, 'uncompressedSize' => 0, 'filenameLength' => strlen($filename), 'extraFieldLength' => 0, ]; $LFH = pack('LSSSSSLLLSSa*', ...array_values([ 'signature' => 0x04034b50, ] + $fileInfo + ['filename' => $filename])); $fileOffset = $written; $written += fwrite($handle, $LFH); $reader = read($entry); foreach ($reader as $chunk) { $written += fwrite($handle, $chunk); $chunk = null; } [ 'uncompressedSize' => $uncompressedSize, 'compressedSize' => $compressedSize, 'crc32' => $crc32 ] = $reader->getReturn(); $fileInfo['crc32'] = $crc32; $fileInfo['compressedSize'] = $compressedSize; $fileInfo['uncompressedSize'] = $uncompressedSize; $DD = pack('LLLL', ...array_values([ 'signature' => 0x08074b50, 'crc32' => $fileInfo['crc32'], 'compressedSize' => $fileInfo['compressedSize'], 'uncompressedSize' => $fileInfo['uncompressedSize'], ])); $written += fwrite($handle, $DD); $dictionary[$filename] = [ 'signature' => 0x02014b50, 'versionMadeBy' => 798, ] + $fileInfo + [ 'fileCommentLength' => 0, 'diskNumber' => 0, 'internalFileAttributes' => 0, 'externalFileAttributes' => 2176057344, 'localFileHeaderOffset' => $fileOffset, 'filename' => $filename, ]; } $EOCD = [ 'signature' => 0x06054b50, 'diskNumber' => 0, 'startDiskNumber' => 0, 'numberCentralDirectoryRecord' => $records = count($dictionary), 'totalCentralDirectoryRecord' => $records, 'sizeOfCentralDirectory' => 0, 'centralDirectoryOffset' => $written, 'commentLength' => 0 ]; foreach ($dictionary as $entryInfo) { $CDFH = pack('LSSSSSSLLLSSSSSLLa*', ...array_values($entryInfo)); $written += fwrite($handle, $CDFH); } $EOCD['sizeOfCentralDirectory'] = $written - $EOCD['centralDirectoryOffset']; $EOCD = pack('LSSSSLLS', ...array_values($EOCD)); $written += fwrite($handle, $EOCD); fclose($handle); echo '  : ' . memory_get_peak_usage(true) . ' ' . PHP_EOL; echo '  : ' . $written . ' ' . PHP_EOL; echo '   `unzip -tq ' . $destination . '`: ' . PHP_EOL; echo '> ' . exec('unzip -tq ' . $destination) . PHP_EOL; echo PHP_EOL; 

рдирддреАрдЬрддрди, рдореБрдЭреЗ рдЖрдХрд╛рд░ рдореЗрдВ 360183 рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдорд┐рд▓рд╛ (рд╣рдорд╛рд░реА 100 рдПрдордмреА рдлрд╝рд╛рдЗрд▓ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХреА рдЧрдИ рдереА, рдЬреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рд╕рдорд╛рди рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ), рдФрд░ рдЕрдирдЬрд╝рд┐рдк рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рдХрд┐ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рдорд┐рд▓реАред

рдирд┐рд╖реНрдХрд░реНрд╖


рдпрджрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдФрд░ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдКрд░реНрдЬрд╛ рдФрд░ рд╕рдордп рд╣реИ, рддреЛ рдореИрдВ рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рдХреНрдпреЛрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрджрд┐ рдЖрдк рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдХрд┐рд╕реА рдФрд░ рдЪреАрдЬ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ - рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕реБрдЭрд╛рд╡ рджреЗрдВ, рдореИрдВ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рд╣рдо рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рд╕рд╛рде рд╕реМрджрд╛ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд╣рд▓реЗ рд╣реА рдмрдврд╝ рдЧрдИ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ рдРрд╕реЗ рдЕрднрд┐рд▓реЗрдЦрд╛рдЧрд╛рд░, рдРрд╕рд╛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдмрд╣реБрдд рдмрд╛рд░ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред



рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдФрд░ рдЖрдкрдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

Source: https://habr.com/ru/post/hi472966/


All Articles