Συμβολοσειρές, bits, και nybbles#

Στο τέλος αυτού του κεφαλαίου θα μπορείτε να πακετάρετε και αποπακετάρετε συμβολοσειρές σταθερού πλάτους, C-style NUL-τερματισμένες συμβολοσειρές, συμβολοσειρές bits, και δεκαεξαδικές συμβολοσειρές - τις τρεις οικογένειες οδηγιών που μοιάζουν με κείμενο.

Τα δυαδικά πρότυπα μεταφέρουν δεδομένα συμβολοσειρών σε διάφορες ξεχωριστές γεύσεις: ωμά bytes, κείμενο με συμπλήρωση κενών, NUL-τερματισμένες συμβολοσειρές C, πεδία bits, αριθμοί κωδικοποιημένοι σε δεκαεξαδικό. Η pack έχει μία οδηγία για το καθένα.

Οι τρεις οδηγίες συμβολοσειρών: a / A / Z#

Και οι τρεις πακετάρουν ακριβώς μία τιμή σε σταθερό πλάτος. Διαφέρουν στο με τι συμπληρώνουν και - κρισίμως - στο τι η unpack αφαιρεί κατά την επιστροφή:

Γράμμα

Byte συμπλήρωσης

Η unpack επιστρέφει

Τυπική χρήση

a

"\0" (NUL)

Όλα τα bytes αμετάβλητα

Αυθαίρετα δυαδικά

A

" " (κενό)

Τελικοί λευκοί χαρακτήρες και NUL αφαιρούνται

Κείμενο ASCII σταθερού πλάτους

Z

"\0" (NUL)

Bytes μέχρι το πρώτο NUL

C-style NUL-τερματισμένο

Το πλάτος είναι ο μετρητής επανάληψης, όχι μετρητής τιμών:

pack "a4", "hi"           # "hi\0\0"
pack "A4", "hi"           # "hi  "
pack "Z4", "hi"           # "hi\0\0"

pack "a4", "abcdef"       # "abcd"  - truncated
pack "A*", "hello"        # "hello" - whatever the value's length is

Το Z εγγυάται τελικό NUL - με μια επιφύλαξη#

Το Z δεσμεύει πάντα χώρο για τουλάχιστον ένα τερματικό NUL:

pack "Z*", "hello"        # "hello\0"   - a free NUL appended
pack "Z5", "hello"        # "hell\0"    - truncated to make room!

Αν ένα πρόγραμμα C στην άλλη πλευρά αναμένει ένα μηδενοτερματισμένο char[32], χρησιμοποιήστε Z32. Θα πακετάρει έως 31 bytes δεδομένων συν τον τερματιστή.

Επιλογή μεταξύ a και A για κείμενο#

  • Τα δεδομένα είναι ASCII, με συμπλήρωση κενών στον δίσκο → A.

  • Τα δεδομένα είναι αυθαίρετα bytes (ενδέχεται να περιέχουν κενά ή NUL ως έγκυρο περιεχόμενο) → a.

Η κλασική παγίδα: πακετάρετε ένα όνομα με A20 και η μορφή επί της γραμμής χρησιμοποιεί συμπλήρωση με NUL. Η unpack "A20" αφαιρεί και κενά και NUL, οπότε φαίνεται εντάξει - αλλά η pack "A20", "bob" θα κάνει πλήρη κύκλο σε "bob " συμπληρωμένο με κενά. Αν οι προδιαγραφές λένε συμπλήρωση με NUL, χρησιμοποιήστε a στην πλευρά του pack.

Επεξεργασμένο παράδειγμα: εγγραφές κειμένου σταθερού πλάτους#

Ένα αρχείο κατάστιχου διατάσσει τα δεδομένα σε στήλες:

0         1         2         3         4
0123456789012345678901234567890123456789012345678
2026-04-22 coffee at the station           3.50
2026-04-23 train to Brussels              42.00

Η στήλη 1-10 είναι η ημερομηνία, 12-38 η περιγραφή, 40-47 το ποσό. Τα κενά είναι μεμονωμένα κενά (byte 11 και byte 39). Η unpack με A10 x A27 x A* ξεφλουδίζει κάθε εγγραφή:

while (<$ledger>) {
    chomp;
    my ($date, $desc, $amount) = unpack "A10 x A27 x A*", $_;
    print "  $date | $desc | $amount\n";
}

Το x παρακάμπτει ένα byte· το A27 καταβροχθίζει τη στήλη περιγραφής και αφαιρεί τελικά κενά· το A* καταβροχθίζει άπληστα τα υπόλοιπα bytes ως ποσό. Η πλευρά εξόδου χρησιμοποιεί ευρύτερα πεδία ώστε τα κενά να επιβιώνουν στον πλήρη κύκλο:

my $line = pack "A11 A28 A8 A*", $date, $desc,
                                 sprintf("%.2f", $amt_left),
                                 sprintf("%12.2f", $amt_right);

Παρατηρήστε το επιπλέον byte σε κάθε πλάτος A - αυτό το μοναδικό επιπλέον byte είναι το κενό στήλης. Ένας συνεπής προϋπολογισμός bytes ανά στήλη είναι αυτό που κάνει τις εγγραφές σταθερού πλάτους διαχειρίσιμες εξαρχής.

Συμβολοσειρές bits: b και B#

Μια συμβολοσειρά bits είναι μια συμβολοσειρά χαρακτήρων "0" και "1" που πακετάρει σε πραγματικά bits. Δύο οδηγίες, που διαφέρουν μόνο στο πώς διαβάζετε κάθε byte:

Οδηγία

Σειρά bits μέσα σε κάθε byte

b

LSB πρώτο - bit 0, 1, 2, 3, 4, 5, 6, 7

B

MSB πρώτο - bit 7, 6, 5, 4, 3, 2, 1, 0

Ο μετρητής επανάληψης είναι ο αριθμός των bits, όχι bytes:

pack "B8", "10001100"      # "\x8c" - MSB first, bit 7 set, bit 3 & 2 set
pack "b8", "00110001"      # "\x8c" - LSB first, same byte

Το B ταιριάζει με τη συνηθισμένη σύμβαση «από αριστερά προς τα δεξιά είναι από υψηλό προς χαμηλό» που βλέπετε σε δυαδικά dumps· το b ταιριάζει με τη σύμβαση που χρησιμοποιούν ορισμένοι καταχωρητές hardware και η ενσωματωμένη vec. Χρησιμοποιήστε B όταν γράφετε έναν «κανονικό» δυαδικό αριθμό, b όταν αντικατοπτρίζετε ένα φύλλο δεδομένων που αριθμεί το bit 0 στα δεξιά.

Μέτρηση ενεργοποιημένων bits#

Μία από τις πιο απρόσμενες χρήσεις της unpack: μέτρηση των ενεργοποιημένων bits σε έναν ενταμιευτή με μία κλήση. Το %32b* αποπακετάρει τα bits και ζητάει ένα άθροισμα 32-bit, που είναι η μέτρηση:

my $n_bits = unpack "%32b*", $mask;

Το πρόθεμα %N υπάρχει μόνο στην unpack - δείτε το κεφάλαιο για την τοποθέτηση για τις άλλες χρήσεις.

Δεκαεξαδικές συμβολοσειρές: h και H#

Οι δεκαεξαδικές συμβολοσειρές είναι η αναπαράσταση κειμένου που διαβάζουν οι περισσότεροι προγραμματιστές - δύο δεκαεξαδικά ψηφία ανά byte. Δύο οδηγίες, που διαφέρουν στη σειρά των nybbles:

Οδηγία

Σειρά nybbles

h

Χαμηλό nybble πρώτο

H

Υψηλό nybble πρώτο

Το H είναι το «κανονικό» δεκαεξαδικό dump - διάβασμα από αριστερά προς δεξιά, υψηλό ψηφίο μετά χαμηλό:

pack "H*", "deadbeef"      # "\xde\xad\xbe\xef"
unpack "H*", "\xde\xad\xbe\xef"   # "deadbeef"

Το h αντιστρέφει τα nybbles κάθε byte - σπάνια αυτό που θέλετε εκτός αν οι προδιαγραφές το λένε ρητά. Αν ο πλήρης κύκλος που περιμένετε δεν είναι αυτός που παίρνετε, δοκιμάστε το άλλο γράμμα.

pack "h*", "ef"            # "\xfe"  (nybbles swapped)
pack "H*", "ef"            # "\xef"

Επιλογή μεταξύ τους#

Έχετε

Καταφύγετε σε

ASCII σε στήλη σταθερού πλάτους στον δίσκο

A

Αυθαίρετα bytes σε θυρίδα σταθερού πλάτους

a

Μια C-style NUL-τερματισμένη συμβολοσειρά

Z

Έναν δυαδικό αριθμό ως συμβολοσειρά από 0 / 1

B

Το ίδιο, με τη σειρά bits της σύμβασης καταχωρητών

b

Δεκαεξαδική συμβολοσειρά στη συνηθισμένη σειρά ανάγνωσης

H

Δεκαεξαδική συμβολοσειρά με εναλλαγμένα nybbles

h

Οι οδηγίες bits, nybbles, και συμβολοσειρών μοιράζονται έναν κανόνα: ο μετρητής επανάληψης ορίζει το πλάτος της μοναδικής τιμής που πακετάρεται, όχι τον αριθμό των τιμών. Αυτό είναι το ένα γεγονός που πρέπει να μεταφέρετε παρακάτω.

Στη συνέχεια: ομάδες () και μετρητές επανάληψης, τα εργαλεία για την εφαρμογή ενός μοτίβου οδηγιών σε λίστα τιμών αγνώστου μήκους.