>>>>> "AQ" == Albert Q <albert.q.p...@gmail.com> 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  ------  u...@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Code Review , Architecture, Development, Training, Support ------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to