الدرس 5 من 9
قراءة البنى
- 15 دقيقة
- 5 فحوص
- 3 تلميحات
- إلى المطلوب
هدف الدرس
قراءة حقول الترويسة بالمكتبة struct
الشرح
حين تفتح ملفًّا ثنائيًّا تجد في أوّله غالبًا ترويسة (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، لكن ترويستنا المخترَعة هنا تقرأ توقيعها بكبير الطرف لتجمع الترتيبين في درس واحد.
المطلوب
عندك ترويسة سجلّ طولها سبعة بايتات. أوّلها الحقل magic في بايتين بكبير الطرف، ثم version في بايت واحد، ثم length في أربعة بايتات بصغير الطرف. اكتب الدالة parse(data) لتقرأها بالدالة struct.unpack وتُرجع قاموسًا مفاتيحه "magic" و"version" و"length".
الفحوص
5 فحوص- الحقل magic مقروء بكبير الطرف
- الحقل version صحيح
- الحقل length مقروء بصغير الطرف
- الدالة parse تعمل على ترويسة أخرى
- مقروءة بالدالة struct.unpack