pack ו־unpack - הדרכה#
pack ו־unpack הם הסריאלייזרים ברמה הנמוכה של Perl. הם ממירים בין ערכי Perl לבין מחרוזות הבתים הגולמיות שפורמטים בינאריים - פרוטוקולי רשת, כותרות קובץ, struct של C, רשומות ברוחב קבוע - נושאים בפועל על החוט.
רוב מתכנתי Perl נתקלים בהם לעיתים רחוקות ושוכחים אותם במהירות. הדרכה זו נמצאת כאן כדי שכאשר תיתקלו בהם, כבר תכירו את צורת הבעיה.
מתי צריך את pack ו־unpack#
פנו אליהם כאשר אתם:
מדברים פרוטוקול חוט - שאילתות DNS, כותרות TCP/IP, פריימים של MQTT, כל דבר עם ״big-endian 16-bit length״ במפרט שלו.
מפענחים פורמט קובץ בינארי - PNG, GIF, WAV, ELF, GZip, Intel HEX, כל הפורמטים שארבעת הבתים הראשונים שלהם הם מספר קסם ולאחריו שדות מספריים ידועים.
חותכים רשומות טקסט ברוחב קבוע - קובצי log, פנקסי הנהלת חשבונות, דוחות מ־mainframe.
unpackנקי יותר מקריאותsubstrמשורשרות ומטפל באי־בהירות של שדה ריק ש־splitמקריס.מעבירים נתונים לקריאת מערכת -
syscall,ioctl, והבנאי הנדירsockaddr_*מצפים לבתים מסודרים כ־struct של C.
לסריאליזציה של טקסט (JSON, YAML, CSV, XML), פנו למודול המתאים במקום. pack מיועד לבינארי.
כיצד הדרכה זו מאורגנת#
כל פרק מלמד נושא אחד ועומד בפני עצמו. אפשר לקרוא אותם לפי הסדר, או לקפוץ לזה שעונה על שאלתכם.
בתים ורוחבים - ספירת בתים, הוראות מספר שלם ברוחב קבוע, ההבחנה בין native ל־fixed.
Endianness - סדר בתים, המתאמים
</>, הקיצורים הניידיםn/N/v/V.מחרוזות -
a/A/Z(בינארי, טקסט, C string), מחרוזות ביטים, מחרוזות hex.קיבוץ ומונים - קבוצות
(), מוני חזרות, צורות[…], הוראת קידומת־מונה־פריטים/.מיקום -
x/X/@/.לתנועה בתוך תבנית מבלי לייצר ערך.פרוטוקולי רשת - בניית ופענוח כותרת שאילתת DNS.
פורמטים של קבצים - פענוח כותרת GIF, הקובץ הקנוני של ״מספר קסם בתוספת שדות קבועים״.
שני פרקים (network-protocols, file-formats) הם דוגמאות מלאות ומפותחות. עברו על אחד מהם לאחר שקראתם די מן הפרקים האחרים כדי לזהות את ההוראות.
סיבוב ראשון הלוך־ושוב#
הדוגמה השימושית הקצרה ביותר של pack ו־unpack עובדים יחדיו - אריזת כתובת IP מנוקדת לארבעה בתים גולמיים וקריאתה חזרה:
my $raw = pack "C4", 192, 168, 1, 42; # "\xc0\xa8\x01\x2a"
my @octets = unpack "C4", $raw; # (192, 168, 1, 42)
C אורז בית אחד ללא־סימן; C4 אורז ארבעה כאלה ברצף. בדרך החוצה, אותה תבנית מושכת אותם חזרה לרשימה של ארבעה מספרים שלמים. כל פורמט בינארי מורכב יותר בנוי כשכבה על גבי הרעיון הזה.
מוסכמות בדוגמאות#
פלט צפוי מופיע כהערת
# …באותה שורה כמו הביטוי שייצר אותו, או ישירות מתחת לבלוק הקוד.הדוגמאות רצות תחת מפרש מוכוון־בתים - ללא
use utf8, ללא פרגמתuse openהמשנה שכבות. אם מופיע מטפל קובץ, יש להניח ש־binmode $fhכבר נקרא.קבועים רב־בתיים כמו
"\xc0\xa8\x01\x2a"נכתבים עם hex escapes במקום ערכי בתים גולמיים כך שהטקסט המודפס תואם את מה שרואים בקוד.