a question about pack

a question about pack

am 22.08.2010 10:33:41 von Albert Q

--0016369c897aa297e3048e65631a
Content-Type: text/plain; charset=ISO-8859-1

Hi

I have a text file containing hex strings such as: 12 34 56 78 90 ab cd ef
now I want to change these hex strings to sequence of bytes with the
relative value of 0x12 0x34 0x56 ....

bellow are my codes

use strict;
use warnings;
sub proc_file
{
my ($in, $out) = @_;
open my $fin, '<', $in or die "$!, $in";
open my $fout, '>', $out or die "$!, $out";
while(<$fin>)
{
my @values = split /\s+/;
print $fout join '' , map { pack 'H*', $_} @values; # method 1
print $fout pack 'H*', join '', @values; # method
2
print $fout pack 'H*', @values; # method
3
}
}

proc_file @ARGV;


The result is that, both method 1 and method 2 works OK, but with method 3,
I only get the first byte. For example,
if @values is 12 34 56 78
pack 'H*', @values will get a string with only one byte 0x12
from perlfun, I found that the pack function will gobble up that many values
from the LIST except for some types, and 'H' is one of these types.
so, if I use
pack 'H*H*H*H*', @values;
I will get the correct result of 4 bytes 0x12 0x34 0x56 0x78

My question is, does there exist some other more simple way to accomplish
this transfrom, for example, just one modifier to tell the pack to use all
items of the LIST?

Thanks & Best Regards
Albert


--
missing the days we spend together

--0016369c897aa297e3048e65631a--

Re: a question about pack

am 22.08.2010 10:51:16 von Uri Guttman

>>>>> "AQ" == Albert Q 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 ------ uri@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-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: a question about pack

am 22.08.2010 13:16:56 von Albert Q

2010/8/22 Uri Guttman
>
> >>>>> "AQ" == Albert Q 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 :)

> =A0AQ> I have a text file containing hex strings such as: 12 34 56 78 90 =
ab cd ef
> =A0AQ> now I want to change these hex strings to sequence of bytes with t=
he
> =A0AQ> relative value of 0x12 0x34 0x56 ....
>
> =A0AQ> sub proc_file
> =A0AQ> {
> =A0AQ> =A0 =A0 while(<$fin>)
> =A0AQ> =A0 =A0 {
> =A0AQ> =A0 =A0 =A0 =A0 my @values  = split /\s+/;
> =A0AQ> =A0 =A0 =A0 =A0 print $fout join '' , map { pack 'H*', $_} @values=
; =A0 # method 1
> =A0AQ> =A0 =A0 =A0 =A0 print $fout pack 'H*', join '', @values; =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 # method
> =A0AQ> 2
> =A0AQ> =A0 =A0 =A0 =A0 print $fout pack 'H*', @values; =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0# method
> =A0AQ> 3
> =A0AQ> =A0 =A0 }
> =A0AQ> }
>
> =A0AQ> The result is that, both method 1 and method 2 works OK, but with =
method 3,
> =A0AQ> I only get the first byte. For example,
> =A0AQ> if @values is 12 34 56 78
> =A0AQ> pack 'H*', @values will get a string with only one byte 0x12
> =A0AQ> from perlfun, I found that the pack function will gobble up that m=
any values
> =A0AQ> from the LIST except for some types, and 'H' is one of these types=
..
> =A0AQ> so, if I use
> =A0AQ> pack 'H*H*H*H*', @values;
> =A0AQ> I will get the correct result of 4 bytes 0x12 0x34 0x56 0x78
>
> =A0AQ> My question is, does there exist some other more simple way to acc=
omplish
> =A0AQ> this transfrom, for example, just one modifier to tell the pack to=
use all
> =A0AQ> items of the LIST?
>
> from the docs on pack:
>
> =A0 =A0 =A0 =A0The "h" and "H" fields pack a string that many nybbles (4-=
bit
> =A0 =A0 =A0 =A0groups, representable as hexadecimal digits, 0-9a-f) long.
>
> =A0 =A0 =A0 =A0If the input string of pack() is longer than needed, extra
> =A0 =A0 =A0 =A0characters are ignored. =A0A "*" for the repeat count of p=
ack()
> =A0 =A0 =A0 =A0means to use all the characters of the input field. =A0On
> =A0 =A0 =A0 =A0unpack()ing the nybbles are converted to a string of hexad=
ecimal
> =A0 =A0 =A0 =A0digits.
>
> 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:
>
> =A0 =A0 =A0 =A0A ()-group is a sub-TEMPLATE enclosed in parentheses. =A0A=
group
> =A0 =A0 =A0 =A0may take a repeat count, both as postfix, and for unpack()=
also
> =A0 =A0 =A0 =A0via the "/" template character. =A0Within each repetition =
of a
> =A0 =A0 =A0 =A0group, positioning with "@" starts again at 0. Therefore, =
the
> =A0 =A0 =A0 =A0result of
>
> =A0 =A0 =A0 =A0pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )
> =A0 =A0 =A0 =A0is 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 =A0------ =A0uri@stemsystems.com =A0-------- =A0http://www.sy=
sarch.com --
> ----- =A0Perl Code Review , Architecture, Development, Training, Support =
------
> --------- =A0Gourmet Hot Cocoa Mix =A0---- =A0http://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: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: a question about pack

am 22.08.2010 14:02:38 von rvtol+usenet

On 2010-08-22 13:16, Albert Q wrote:

> pack '(H*)*', @values will get the correct result.

Now go and read perlpacktut a few times.

--
Ruud

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

Re: a question about pack

am 22.08.2010 16:55:28 von Uri Guttman

>>>>> "AQ" == Albert Q writes:

AQ> 2010/8/22 Uri Guttman
>>
>> >>>>> "AQ" == Albert Q 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> but I only have this mailing list, and I think it is not a heigh level
AQ> problem :)

so you should learn about other perl resources like usenet, perl monks
and lists.perl.org. and yes, pack IS a high level problem. perl newbies
(the target of this list) rarely need to use pack/unpack.

uri

--
Uri Guttman ------ uri@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-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: a question about pack

am 23.08.2010 13:08:58 von Albert Q

2010/8/22 Dr.Ruud :
> On 2010-08-22 13:16, Albert Q wrote:
>
>> pack '(H*)*', @values =A0 will get the correct result.
>
> Now go and read perlpacktut a few times.

This problem is documented in perlpacktut clearly. Thank you.


> --
> Ruud
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> http://learn.perl.org/
>
>
>



--=20
missing the days we spend together

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

Re: a question about pack

am 23.08.2010 13:11:50 von Albert Q

2010/8/22 Uri Guttman :
>>>>>> "AQ" == Albert Q writes:
>
> =A0AQ> 2010/8/22 Uri Guttman
> =A0>>
> =A0>> >>>>> "AQ" == Albert Q writes:
> =A0>>
> =A0>> a quick comment. pack is most likely not a beginner issue. i am sur=
e you
> =A0>> will get help here but think about better forums for asking about
> =A0>> pack. there are plenty. pack is powerful and sometimes dark magic e=
ven
> =A0>> to experienced perl hackers (i know on very high level hacker who n=
ever
> =A0>> used pack/unpack.).
>
> =A0AQ> but I only have this mailing list, and I think it is not a heigh l=
evel
> =A0AQ> problem :)
>
> so you should learn about other perl resources like usenet, perl monks
> and lists.perl.org. and yes, pack IS a high level problem. perl newbies
> (the target of this list) rarely need to use pack/unpack.

Yes, the PerlMonks maybe a good choice.


> uri
>
> --
> Uri Guttman =A0------ =A0uri@stemsystems.com =A0-------- =A0http://www.sy=
sarch.com --
> ----- =A0Perl Code Review , Architecture, Development, Training, Support =
------
> --------- =A0Gourmet Hot Cocoa Mix =A0---- =A0http://bestfriendscocoa.com=
---------
>



--=20
missing the days we spend together

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