2010/8/22 Uri Guttman <[email protected]>
>
> >>>>> "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.).
but I only have this mailing list, and I think it is not a heigh level
problem :)
> 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 ---------
Yes, it works well !
pack '(H*)*', @values will get the correct result.
Thanks a lot !
--
missing the days we spend together
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/