Βαθμωτά και συμβολοσειρές · Δεδομένα σταθερού μήκους
pack#
Μετατρέπει μια λίστα τιμών Perl σε δυαδική συμβολοσειρά σύμφωνα με ένα πρότυπο.
Η pack είναι ο χαμηλού επιπέδου σειριοποιητής: περιγράφετε τη διάταξη bytes με ένα TEMPLATE, της παραδίδετε μια LIST τιμών, και επιστρέφει ένα βαθμωτό του οποίου οι χαρακτήρες είναι η συνενωμένη κωδικοποίηση σε επίπεδο μηχανής αυτών των τιμών. Είναι το αντίστροφο της unpack και ο καθιερωμένος τρόπος για να κατασκευάζετε εγγραφές σταθερού πλάτους, πρωτόκολλα επί της γραμμής, διατάξεις struct της C, ωμές διευθύνσεις IP για sockaddr_in, και κάθε άλλο φορτίο επιπέδου byte που η Perl δεν μοντελοποιεί ως τύπο πρώτης τάξης.
This page is a directive reference. For a narrative introduction
«I have this wire protocol, how do I parse it?» - start at the pack/unpack tutorial.
Σύνοψη#
my $bytes = pack TEMPLATE, LIST;
my $ip = pack "C4", split /\./, "192.168.1.1";
my $rec = pack "Z8 Z8 L", $user, $host, $ts;
Τι επιστρέφεται#
Ένα απλό βαθμωτό Perl που κρατά τα πακεταρισμένα bytes. Το μήκος του είναι το άθροισμα των πλατών κάθε οδηγίας του προτύπου· το περιεχόμενό του είναι δυαδικό και ενδέχεται να περιέχει ενσωματωμένα bytes NUL. Μεταχειριστείτε το ως συμβολοσειρά bytes, όχι ως κείμενο - γράφοντάς το σε handle με στρώμα :utf8 ή :encoding(…) θα το επανακωδικοποιήσει. Χρησιμοποιήστε binmode $fh ή ανοίξτε με ">:raw" πριν την έκδοση.
Προεπιλεγμένα το αποτέλεσμα είναι σε κατάσταση χαρακτήρων (C0). Ένα πρότυπο που ξεκινά με U, ή που μεταβαίνει σε U0 στη μέση του προτύπου, παράγει αντ” αυτού μια συμβολοσειρά Unicode κωδικοποιημένη σε UTF-8. Μη χρησιμοποιείτε αυτό ως υποκατάστατο του αρθρώματος Encode.
Σύνταξη προτύπου#
Ένα TEMPLATE είναι μια ακολουθία από οδηγίες. Κάθε οδηγία είναι ένα γράμμα ASCII, προαιρετικά ακολουθούμενο από:
μια μετρητή επανάληψης - έναν δεκαδικό ακέραιο,
*, ή[…]έναν ή περισσότερους τροποποιητές -
!,<,>μια ομάδα -
( … )συγκεντρώνει οδηγίες ώστε ένας μετρητής επανάληψης ή τροποποιητής endianness να εφαρμόζεται στο σύνολο
Οι λευκοί χαρακτήρες μεταξύ οδηγιών αγνοούνται. Το # εισάγει σχόλιο που τρέχει μέχρι το τέλος της γραμμής - η ίδια σύμβαση με τον πηγαίο κώδικα Perl.
Πίνακας οδηγιών#
Όλες οι οδηγίες της pack σε ένα μέρος. Το W είναι το πλάτος σε bytes ανά καταναλωμένο βαθμωτό (ένα C καταναλώνει μία τιμή και παράγει ένα byte· ένα a3 καταναλώνει μία τιμή και παράγει τρία bytes). Στήλη Endian: native σημαίνει η σειρά bytes του CPU· big / little είναι σταθερά ανεξάρτητα από τον υπολογιστή.
Οδηγία | Καταναλώνει | W | Προσημασμένο | Endian | Τροποποιητές | Σημειώσεις |
|---|---|---|---|---|---|---|
| 1 συμβολοσειρά | μετρητής | - | - | - | Συμπληρώνεται με |
| 1 συμβολοσειρά | μετρητής | - | - | - | Συμπληρώνεται με κενά ως το πλάτος |
| 1 συμβολοσειρά | μετρητής | - | - | - | Τερματίζεται με |
| 1 συμβολοσειρά | μετρητής/8 | - | - | - | Συμβολοσειρά bits, LSB πρώτο μέσα σε κάθε byte |
| 1 συμβολοσειρά | μετρητής/8 | - | - | - | Συμβολοσειρά bits, MSB πρώτο μέσα σε κάθε byte |
| 1 συμβολοσειρά | μετρητής/2 | - | - | - | Δεκαεξαδική συμβολοσειρά, το κάτω nybble πρώτο |
| 1 συμβολοσειρά | μετρητής/2 | - | - | - | Δεκαεξαδική συμβολοσειρά, το άνω nybble πρώτο |
| 1 ακέραιος | 1 | ναι | - | - | Προσημασμένο char |
| 1 ακέραιος | 1 | όχι | - | - | Μη προσημασμένο char (οκτάδα) |
| 1 ακέραιος | 1 | όχι | - | - | Μη προσημασμένο char· επιτρέπει τιμές πάνω από 255 σε κατάσταση |
| 1 ακέραιος | 2 | ναι | native |
|
|
| 1 ακέραιος | 2 | όχι | native |
|
|
| 1 ακέραιος | 4 | ναι | native |
|
|
| 1 ακέραιος | 4 | όχι | native |
|
|
| 1 ακέραιος | native | ναι | native |
|
|
| 1 ακέραιος | native | όχι | native |
|
|
| 1 ακέραιος | 8 | ναι | native |
| Απαιτεί Perl με 64-bit ακεραίους |
| 1 ακέραιος | 8 | όχι | native |
| Απαιτεί Perl με 64-bit ακεραίους |
| 1 ακέραιος | 2 | όχι | big |
| Φορητή σειρά δικτύου· |
| 1 ακέραιος | 4 | όχι | big |
| Φορητή σειρά δικτύου· |
| 1 ακέραιος | 2 | όχι | little |
| Σειρά «VAX»· |
| 1 ακέραιος | 4 | όχι | little |
| Σειρά «VAX»· |
| 1 ακέραιος | μέγεθος IV | ναι | native |
| Εσωτερικός προσημασμένος ακέραιος της Perl |
| 1 ακέραιος | μέγεθος UV | όχι | native |
| Εσωτερικός μη προσημασμένος ακέραιος της Perl |
| 1 αριθμός | 4 | - | native |
| IEEE 754 απλής ακρίβειας |
| 1 αριθμός | 8 | - | native |
| IEEE 754 διπλής ακρίβειας |
| 1 αριθμός | μέγεθος NV | - | native |
| Εσωτερικός float της Perl ( |
| 1 αριθμός | ποικίλλει | - | native |
| Long double· η μορφή ποικίλλει ανά πλατφόρμα |
| 1 συμβολοσειρά / | ptr | - | native |
| Δείκτης σε συμβολοσειρά τερματισμένη με |
| 1 συμβολοσειρά / | ptr | - | native |
| Δείκτης σε ενταμιευτή σταθερού μήκους· μετρητής = μήκος ενταμιευτή |
| 1 συμβολοσειρά | ποικίλλει | - | - | - | Κωδικοποίηση uuencode· μετρητής = μέγιστα bytes ανά γραμμή εξόδου (προεπιλογή 45) |
| 1 σημείο κώδικα | ποικίλλει | - | - | - | Αριθμός χαρακτήρα Unicode· κωδικοποιείται σε UTF-8 σε κατάσταση |
| 1 ακέραιος ≥ 0 | ποικίλλει | όχι | - | - | Ακέραιος συμπιεσμένος κατά BER, big-endian βάσης-128 |
| τίποτα | 1 | - | - |
| Εισάγει ένα |
| τίποτα | −1 | - | - |
| Επιστροφή κατά ένα byte· το |
| τίποτα | απόλυτο | - | - |
| Συμπληρώνει με μηδενικά ή αποκόπτει στη θέση N μέσα στην ομάδα |
| 1 ακέραιος | απόλυτο | - | - |
| Συμπληρώνει με μηδενικά ή αποκόπτει στη θέση που δίνει η τιμή |
| - | - | - | - |
| Ομάδα: ο μετρητής επανάληψης και η endianness διαδίδονται προς τα μέσα |
| - | - | - | - | - | Μόνο για unpack. Στην pack, χρησιμοποιήστε length-item |
Οι τροποποιητές:
Τροποποιητής | Αποτέλεσμα |
|---|---|
| Στα |
| Εξαναγκάζει σε big-endian σειρά bytes («το μεγάλο άκρο αγγίζει την κατασκευή»). |
| Εξαναγκάζει σε little-endian σειρά bytes. |
Εφαρμοζόμενα σε ομάδα, τα < / > διαδίδονται σε κάθε οδηγία με σειρά bytes μέσα στην ομάδα και αγνοούνται σιωπηλά από τις οδηγίες που δεν τα δέχονται.
Μετρητές επανάληψης#
Ένα γράμμα οδηγίας μπορεί να ακολουθείται από:
έναν αριθμό
N- εφαρμόζει την οδηγία τόσες φορές, καταναλώνονταςNτιμές από τηLIST*- καταναλώνει όλες τις υπόλοιπες τιμές· για ταx/X/@αυτό ισοδυναμεί με0· για τοuεπιλέγει την προεπιλογή των 45[N]- ισοδύναμο με γυμνόN[template]- ο μετρητής επανάληψης είναι το μήκος σε bytes του πακεταρισμένου template. Τοx[L]παρακάμπτει τόσα bytes όσα ένα πακεταρισμένο long· τοx![d]ευθυγραμμίζει σε όριο double
Οι οδηγίες συμβολοσειρών και bit/nybble μεταχειρίζονται τον μετρητή ως πλάτος μίας μόνο τιμής, όχι ως πλήθος τιμών: το pack "A4", "abcdef" παράγει "abcd", όχι τέσσερα αντίγραφα του "abcdef".
Ομαδοποίηση#
Οι παρενθέσεις ομαδοποιούν οδηγίες. Μια ομάδα μπορεί να πάρει μετρητή επανάληψης ή τροποποιητή endianness:
pack "(sl)<", -42, 4711 # same as "s<l<", -42, 4711
pack "(CCS)*", @triplets # repeat group for every triplet
Within each repetition of a group, @ positioning starts over at 0
pack '@1A((@2A)@3A)', qw(X Y Z)produces"\0X\0\0YZ".
Φορτία με πρόθεμα μήκους (/)#
Γράψτε length-item/sequence-item. Το μήκος υπολογίζεται από την τιμή της ακολουθίας και πακετάρεται σύμφωνα με το length-item· στη συνέχεια η ίδια η ακολουθία πακετάρεται σύμφωνα με το sequence-item:
my $msg = pack "n/a*", "hello, world";
# "\x00\x0chello, world" - 16-bit big-endian length, then the bytes
Η οδηγία μήκους μπορεί να είναι οποιαδήποτε ακέραια οδηγία (n, N, w, C, …) ή ακόμη και οδηγία συμβολοσειράς (A4, Z*) όταν θέλετε το μήκος γραμμένο ως ASCII.
Παραδείγματα#
Κατασκευή εγγραφής σταθερού πλάτους με δύο συμβολοσειρές τερματισμένες με NUL και ένα 32-bit native χρονοσφραγίδα:
my $rec = pack "Z8 Z8 L", "alice", "server01", $now;
# 8 + 8 + 4 = 20 bytes
Φορητή σειρά bytes δικτύου - προτιμήστε n / N / v / V έναντι οδηγιών native πλάτους όταν τα bytes εγκαταλείπουν τη μηχανή:
my $be = pack "n N", 42, 4711; # big-endian 16 + 32 bit
my $le = pack "v V", 42, 4711; # little-endian
my $sx = pack "s>l>", -42, 4711; # signed big-endian via modifier
my $gx = pack "(sl)<", -42, 4711; # signed little-endian via group
Ευθυγραμμίστε ένα πεδίο μέσα σε ένα C struct. Το x![d] εισάγει ακριβώς τόσα bytes NUL ώστε να φτάσει στο επόμενο πολλαπλάσιο του πλάτους ενός double:
# struct { char c; double d; char cc[2]; }
my $s = pack "c x![d] d c2", $c, $d, $c1, $c2;
Πλήρης κύκλος μέσα από δεκαεξαδική συμβολοσειρά:
my $raw = pack "H*", "deadbeef"; # "\xde\xad\xbe\xef"
my $hex = unpack "H*", $raw; # "deadbeef"
Οριακές περιπτώσεις#
Πολύ λίγες τιμές: οι τιμές που λείπουν αντιμετωπίζονται ως
"". Τοpack "A4 A4", "hi"αποδίδει"hi \0\0\0\0", όχι μοιραίο σφάλμα.Πάρα πολλές τιμές: οι επιπλέον αγνοούνται σιωπηλά.
aέναντιAέναντιZ: και τα τρία συμπληρώνουν σε ακριβές πλάτος. Τοaσυμπληρώνει μεNUL, τοAσυμπληρώνει με κενά, τοZσυμπληρώνει μεNULκαι εγγυάται τελικόNUL- οπότε τοZ8κωδικοποιεί το πολύ 7 bytes δεδομένων συν τον τερματιστή.Πλάτος χαρακτήρων έναντι πλάτους bytes - η μοναδική πιο κοινή παγίδα. Οι μετρητές για τα
a/A/Zκαι οι μετατοπίσεις για τα@/.είναι σε χαρακτήρες της πακεταρισμένης συμβολοσειράς, όχι σε bytes. Σε κατάστασηC0ένας χαρακτήρας είναι ένα byte· σε κατάστασηU0ένας χαρακτήρας μπορεί να καλύπτει πολλαπλά bytes UTF-8. Χρησιμοποιήστε τον τροποποιητή!στα@/.όταν χρειάζεστε μετατοπίσεις σε bytes ανεξάρτητα από την κατάσταση.Endianness στα
s/S/l/L/i/I/q/Q: μόνο native, όχι φορητή. Χρησιμοποιήστεn/N/v/Vή εφαρμόστε ρητά>/<. Ταf/dείναι ομοίως native· από μόνο του το IEEE 754 δεν καθορίζει endianness.Inf/NaNπακεταρισμένα ως ακέραιοι: μοιραίο σφάλμα. Δεν υπάρχει λογική αντιστοίχιση.q/Qσε Perl μη 64-bit: εγείρει εξαίρεση.Τα
pκαιPαποτυπώνουν δείκτες στη μνήμη του καλούντος. Το αντικείμενο αναφοράς πρέπει να παραμείνει ζωντανό μέχρι να καταναλωθεί η πακεταρισμένη συμβολοσειρά - μια προσωρινή συμβολοσειρά που διαβιβάστηκε στοpμπορεί να αποδεσμευτεί πριν τη διαβάσετε πίσω. Αποφύγετέ τα εκτός κώδικα XS.Ομαδοποίηση και
@: η τοποθέτηση με@ξεκινά ξανά από το 0 μέσα σε κάθε επανάληψη μιας ομάδας. Τοpack '@1A((@2A)@3A)', qw(X Y Z)παράγει"\0X\0\0YZ", όχι αυτό που υποδηλώνει μια απλοϊκή ανάγνωση.Απώλεια κατά τον κύκλο κινητής υποδιαστολής: η Perl αποθηκεύει αριθμούς ως double, οπότε γενικά
unpack("f", pack("f", $x))δεν ισούται με την$x- το πακετάρισμα μέσα από απλή ακρίβεια αποκόπτει.Εγγραφή πακεταρισμένων bytes σε handle κειμένου: handle με
:utf8ή:encoding(…)θα επανακωδικοποιήσει τα bytes. Χρησιμοποιήστεbinmode $fhή ανοίξτε με">:raw".
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
unpack- η αντίστροφη λειτουργία· ίδια γλώσσα προτύπωνsprintf- μορφοποιημένη έξοδος κειμένου αντί για δυαδικά bytesvec- πρόσβαση επιπέδου bit σε συμβολοσειρά χωρίς πρότυποsyswrite- εγγραφή πακεταρισμένης συμβολοσειράς bytes χωρίς εκπλήξεις PerlIOΟδηγός pack/unpack - προσανατολισμένη σε εργασίες περιδιάβαση με λυμένα παραδείγματα πρωτοκόλλων και μορφών αρχείων