>>>>> "AQ" == Albert Q <[email protected]> writes:
a quick comment. pack is most likely not a beginner issue. i am sure you
will get help here but think about better forums for asking about
pack. there are plenty. pack is powerful and sometimes dark magic even
to experienced perl hackers (i know on very high level hacker who never
used pack/unpack.).
AQ> I have a text file containing hex strings such as: 12 34 56 78 90 ab cd ef
AQ> now I want to change these hex strings to sequence of bytes with the
AQ> relative value of 0x12 0x34 0x56 ....
AQ> sub proc_file
AQ> {
AQ> while(<$fin>)
AQ> {
AQ> my @values = split /\s+/;
AQ> print $fout join '' , map { pack 'H*', $_} @values; # method 1
AQ> print $fout pack 'H*', join '', @values; #
method
AQ> 2
AQ> print $fout pack 'H*', @values; #
method
AQ> 3
AQ> }
AQ> }
AQ> The result is that, both method 1 and method 2 works OK, but with method
3,
AQ> I only get the first byte. For example,
AQ> if @values is 12 34 56 78
AQ> pack 'H*', @values will get a string with only one byte 0x12
AQ> from perlfun, I found that the pack function will gobble up that many
values
AQ> from the LIST except for some types, and 'H' is one of these types.
AQ> so, if I use
AQ> pack 'H*H*H*H*', @values;
AQ> I will get the correct result of 4 bytes 0x12 0x34 0x56 0x78
AQ> My question is, does there exist some other more simple way to accomplish
AQ> this transfrom, for example, just one modifier to tell the pack to use all
AQ> items of the LIST?
from the docs on pack:
The "h" and "H" fields pack a string that many nybbles (4-bit
groups, representable as hexadecimal digits, 0-9a-f) long.
If the input string of pack() is longer than needed, extra
characters are ignored. A "*" for the repeat count of pack()
means to use all the characters of the input field. On
unpack()ing the nybbles are converted to a string of hexadecimal
digits.
the point is that H and h pack into and from a single string. hex is
usually in a string and the byte value is also a string.
there is a newer feature (dunno which perl version got it first) which
is subtemplating (like grouping in a regex. the docs say this:
A ()-group is a sub-TEMPLATE enclosed in parentheses. A group
may take a repeat count, both as postfix, and for unpack() also
via the "/" template character. Within each repetition of a
group, positioning with "@" starts again at 0. Therefore, the
result of
pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )
is the string "\0a\0\0bc".
so your solution is this:
perl -le 'print unpack "H*", pack( "(H2)*", qw( 10 ab 9f ))'
10ab9f
as you can see it takes a list of hex and pack and unpacks it as
expected.
uri
--
Uri Guttman ------ [email protected] -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/