الدرس 5 من 9

قراءة البنى

هدف الدرس

قراءة حقول الترويسة بالمكتبة struct

01

الشرح

حين تفتح ملفًّا ثنائيًّا تجد في أوّله غالبًا ترويسة (header)، وهي حقول متتالية بأطوال ثابتة، هذا بايتان وذاك أربعة. وقراءتها حقلًا حقلًا بالقصّ والدالة int.from_bytes تطول، ولهذا جاءت المكتبة struct التي تقرأ عدّة حقول دفعة واحدة بنصّ قصير من أحرف التنسيق (format characters):

  • الرمزان < و> في أوّل النصّ يحدّدان الترتيب، صغير الطرف أو كبير الطرف.
  • الحرف B بايت بلا إشارة، وH بايتان، وI أربعة بايتات، وQ ثمانية.
  • الأحرف الصغيرة b وh وi وq بالأطوال نفسها لكن بإشارة، أي تقبل السالب.
  • الصيغة 4s تقرأ أربعة بايتات كما هي.

فالسطر struct.unpack("<IHB", data) يقرأ أربعة بايتات ثم اثنين ثم واحدًا، كلّها بصغير الطرف، ويُرجع صفًّا بالقيم الثلاث. ويجب أن يساوي طول data مجموع أطوال الحقول بالضبط وإلا رمى خطأً، والدالة struct.calcsize("<IHB") تخبرك بهذا الطول. واكتب رمز الترتيب دائمًا في أوّل النصّ، فبدونه تتبع المكتبة ترتيب جهازك وتضيف حشوًا بين الحقول.

ولكل نصّ تنسيق رمز ترتيب واحد، فإن اختلف الترتيب بين حقول ترويسة واحدة قرأتها على دفعتين، كل دفعة بنصّها وبجزئها من البايتات. والبايتان 4d 5a في أوّل header هما الحرفان MZ اللذان يبدأ بهما كل ملف تنفيذي في ويندوز. وويندوز نفسه يقرأ هذين البايتين عددًا بصغير الطرف فيساويان 0x5A4D، لكن ترويستنا المخترَعة هنا تقرأ توقيعها بكبير الطرف لتجمع الترتيبين في درس واحد.

02

المطلوب

عندك ترويسة سجلّ طولها سبعة بايتات. أوّلها الحقل magic في بايتين بكبير الطرف، ثم version في بايت واحد، ثم length في أربعة بايتات بصغير الطرف. اكتب الدالة parse(data) لتقرأها بالدالة struct.unpack وتُرجع قاموسًا مفاتيحه "magic" و"version" و"length".

الفحوص

5 فحوص
  1. الحقل magic مقروء بكبير الطرف
  2. الحقل version صحيح
  3. الحقل length مقروء بصغير الطرف
  4. الدالة parse تعمل على ترويسة أخرى
  5. مقروءة بالدالة struct.unpack
main.py
المخرجاتPython (Pyodide)

نحمّل بيئة Python الآن. يحدث هذا مرّة واحدة فقط، ثم يحفظها متصفّحك.

–/5

يبدأ الفحص حين تجهز البيئة.

تجد 5 فحوص في بطاقة «المطلوب».