pack και unpack - ένας οδηγός εκμάθησης#
Οι pack και unpack είναι οι σειριοποιητές χαμηλού επιπέδου της Perl. Μετατρέπουν μεταξύ τιμών της Perl και των ωμών συμβολοσειρών bytes που τα δυαδικά πρότυπα - πρωτόκολλα δικτύου, headers αρχείων, δομές C, εγγραφές σταθερού πλάτους - μεταφέρουν πραγματικά επί της γραμμής.
Οι περισσότεροι προγραμματιστές της Perl τις συναντούν σπάνια και τις ξεχνούν γρήγορα. Αυτός ο οδηγός εκμάθησης υπάρχει ώστε όταν τις συναντήσετε, να γνωρίζετε ήδη το σχήμα του προβλήματος.
Πότε χρειάζεστε τις pack και unpack#
Καταφύγετε σε αυτές όταν:
Μιλάτε ένα πρωτόκολλο επί της γραμμής - ερωτήματα DNS, headers TCP/IP, πλαίσια MQTT, οτιδήποτε έχει «big-endian 16-bit length» στις προδιαγραφές του.
Αναλύετε ένα δυαδικό πρότυπο αρχείου - PNG, GIF, WAV, ELF, GZip, Intel HEX, όλα τα πρότυπα των οποίων τα πρώτα τέσσερα bytes είναι ένας μαγικός αριθμός ακολουθούμενος από γνωστά ακέραια πεδία.
Τεμαχίζετε εγγραφές κειμένου σταθερού πλάτους - αρχεία καταγραφής, λογιστικά κατάστιχα, αναφορές από mainframes. Η
unpackείναι πιο καθαρή από αλυσιδωτές κλήσειςsubstrκαι χειρίζεται την αμφισημία κενών πεδίων που ηsplitκαταρρέει.Περνάτε δεδομένα σε μια κλήση συστήματος - οι
syscall,ioctl, και ο σπάνιος κατασκευαστήςsockaddr_*αναμένουν bytes διατεταγμένα ως struct της C.
Για σειριοποίηση κειμένου (JSON, YAML, CSV, XML), καταφύγετε στο κατάλληλο άρθρωμα. Η pack είναι για δυαδικά.
Πώς είναι οργανωμένος αυτός ο οδηγός εκμάθησης#
Κάθε κεφάλαιο διδάσκει ένα θέμα και στέκεται αυτόνομα. Μπορείτε να τα διαβάσετε με τη σειρά, ή να μεταπηδήσετε σε αυτό που απαντά στο ερώτημά σας.
Bytes και πλάτη - μέτρηση bytes, οδηγίες ακεραίων σταθερού πλάτους, η διάκριση native έναντι fixed.
Endianness - σειρά bytes, οι τροποποιητές
</>, οι φορητές συντομεύσειςn/N/v/V.Συμβολοσειρές -
a/A/Z(δυαδική, κείμενο, συμβολοσειρά C), συμβολοσειρές bits, δεκαεξαδικές συμβολοσειρές.Ομαδοποίηση και μετρητές - ομάδες
(), μετρητές επανάληψης, μορφές[…], η οδηγία/ως πρόθεμα μετρητή στοιχείων.Τοποθέτηση -
x/X/@/.για μετακίνηση μέσα σε ένα πρότυπο χωρίς παραγωγή τιμής.Πρωτόκολλα δικτύου - κατασκευή και ανάλυση ενός header ερωτήματος DNS.
Πρότυπα αρχείων - ανάλυση ενός header GIF, του κανονικού αρχείου «μαγικός αριθμός συν σταθερά πεδία».
Δύο κεφάλαια (network-protocols, file-formats) είναι πλήρως επεξεργασμένα παραδείγματα. Διατρέξτε ένα από αυτά αφού έχετε διαβάσει αρκετά από τα άλλα κεφάλαια για να αναγνωρίζετε τις οδηγίες.
Μια πρώτη ολοκληρωμένη διαδρομή#
Το συντομότερο χρήσιμο παράδειγμα των pack και unpack που συνεργάζονται - η πακετάρισμα μιας διεύθυνσης IP σε μορφή τετράδας με τελείες σε τέσσερα ωμά bytes και η εκ νέου ανάγνωσή της:
my $raw = pack "C4", 192, 168, 1, 42; # "\xc0\xa8\x01\x2a"
my @octets = unpack "C4", $raw; # (192, 168, 1, 42)
Το C πακετάρει ένα μη προσημασμένο byte· το C4 πακετάρει τέσσερα διαδοχικά. Στην έξοδο, το ίδιο πρότυπο τα ανασύρει σε μια λίστα τεσσάρων ακεραίων. Κάθε πιο πολύπλοκο δυαδικό πρότυπο χτίζεται πάνω σε αυτή την ιδέα.
Συμβάσεις στα παραδείγματα#
Η αναμενόμενη έξοδος εμφανίζεται ως ενσωματωμένο σχόλιο
# …στην ίδια γραμμή με την έκφραση που την παρήγαγε, ή ακριβώς κάτω από το μπλοκ κώδικα.Τα παραδείγματα τρέχουν σε διερμηνέα προσανατολισμένο σε bytes - χωρίς
use utf8, χωρίς pragmause openπου αλλάζει στρώματα. Αν εμφανιστεί ένα filehandle, υποθέστε ότι τοbinmode $fhέχει ήδη κληθεί.Οι σταθερές πολλαπλών bytes όπως
"\xc0\xa8\x01\x2a"γράφονται με δεκαεξαδικές διαφυγές αντί για ωμές τιμές bytes ώστε το εκτυπωμένο κείμενο να συμφωνεί με αυτό που βλέπετε στον κώδικα.