كيف يبدو أرشيف الرمز البريدي وماذا يمكننا أن نفعل حيال ذلك

يوم جيد يا عزيز هبر!

على مدى نصف العام الماضي ، قادني الطريق الملتوي لمشاريعي للحيوانات الأليفة إلى هذه الغابة ، حيث لا يزال من غير الممكن الخروج. وقد بدأ كل شيء على نحو غير ضار - موقع يحتوي على صور ، ولكن إحساس بالكمال ، والسعي وراء الهدية الترويجية ، وكذلك بعض ميزات عقلي ، حولت هذا ، كما هو مخطط له في الأصل ، لمسافة صغيرة إلى رحلة طويلة حقيقية. حسنًا ، حسنًا ، كما اعتاد المرء أن يقول ثوريًا: "تعلم ، ادرس ودرس مرة أخرى" ، وأنا ، ويلي ، نيلي ، يجب أن أتبع هذا النصح.

أوه ، شيء كان يصرف انتباهنا عن الموضوع الرئيسي. لن أتعرض لخطب مطولة بعد الآن ، لكنني سأذهب إلى العمل.

إنشاء أرشيف مضغوط


من حيث المبدأ ، لن أعد كتابة المواصفات هنا. على العموم ، لا معنى لوصف الهيكل أيضًا ، لأن كل هذا تم قبلي .

بالنسبة لأولئك الذين هم كسولون جدًا في متابعة الروابط ، سأشرح بإيجاز أن أي أرشيف مضغوط يجب أن يحتوي على:

  • إدخال الملف:
    • رأس الملف المحلي
    • بيانات مفيدة
    • واصف البيانات (اختياري ، يُستخدم عندما لا نعرف حجم الملف وتجزئته حتى نقرأه حتى النهاية)
  • رأس ملف الدليل المركزي (لكل ملف. يشبه جدول محتويات كتاب ، حيث يشار إلى كل قسم والصفحة التي يمكن العثور عليها)
  • نهاية الدليل المركزي

مع العلم بذلك ، يمكننا محاولة كتابة أرشيف بسيط يحتوي على ملفين فقط:

<?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; 

حاول تشغيل هذا الكود البدائي وسوف يعطيك الإخراج ملف Lorem.zip الذي سيحتوي على 1.txt و 2.txt.

ولماذا؟


بالطبع ، سيقول أي شخص مناسب أن كتابة الأرشيفات في php هي مهمة عقيمة ، خاصة وأن التنسيق مثل zip ، يوجد مجموعة من التطبيقات الجاهزة لكل الأذواق واللون. وفي نفس php هناك مكتبات جاهزة. سأقول ذلك أيضا :)

لكن لماذا إذن ، هذا المقال برمته ، لماذا قضيت وقتاً في كتابته وأنت تقرأه؟
وبعد ذلك ، أن كل شيء ليس بهذه البساطة ومعرفة كيفية عمل الرمز البريدي ، يفتح لنا بعض الاحتمالات الإضافية.

أولاً ، آمل ، قليلاً على الأقل ، لكنها ستساعد أولئك الذين يريدون فهم بنية الرمز البريدي.
وثانيا ، إنشاء الأرشيف بأيدينا ، لدينا سيطرة ، والأهم من ذلك ، الوصول إلى بياناتها الداخلية.

يمكننا احتساب "رأس الملف المحلي" و "رأس ملف الدليل المركزي" مسبقًا ، ثم إنشاء أرشيف مضغوط عند الطلب باستخدام أي محتوى وترتيب الملفات ، ببساطة استبدال هذه البيانات. وليس النفقات العامة باستثناء I / O.

أو ، يمكننا تسجيل الأرشيف ، وتحميله ، على سبيل المثال ، إلى السحابة ، التي تدعم التنزيل المجزأ ، ومعرفة الإزاحات لكل ملف ، الحصول على أي من ملفات الأرشيف ، كما لو لم يكن في الأرشيف على الإطلاق ، إضافة ملف واحد فقط عنوان الطلب. ثم كل هذا يمكن أن يكون بروكسي و ...

حسنًا ، دعونا لا نتقدم على أنفسنا. إذا كنت مهتمًا بهذا الموضوع ، فسأحاول في المقالات التالية التفكير في هذه الفرص وإظهار كيفية استخدامها.


'diskNumber' => 0 ، // عادةً ما صادفت 0 في كل مكان ، وعلى وجه الخصوص قررت عدم الخوض في
كما اقترح بيريز ، رقم المجلد في أرشيف متعدد المجلدات.

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


All Articles