extract number from binary string

L

Looden

Hi
I'm parsing a binary string, which encodes a number.
I don't know the length of the string in advance: 1, 2, 3 or 4 bytes.
The bytes of the string are in network order.
How can I retrieve the number?

I've written this sub, there must be a better way:

sub parse_number {
my $arg = shift;
my $size = length($arg);
my $value = 0;
my $buf;
for (my $i=($size-1);$i>=0;$i--){
$buf = unpack "C", (substr $arg, $i, 1);
$value += $buf * (256**($size-$i-1));
}
return $value;
}

Note: If the length of the string was always 2 bytes, I could just do:
sub parse_n { return unpack "n", shift; }

Thanks in advance.
 
U

Uri Guttman

L> I'm parsing a binary string, which encodes a number. I don't know
L> the length of the string in advance: 1, 2, 3 or 4 bytes. The bytes
L> of the string are in network order. How can I retrieve the number?

L> sub parse_number {
L> my $arg = shift;

pick a better name for that. $arg is generic.

L> my $size = length($arg);
L> my $value = 0;
L> my $buf;
L> for (my $i=($size-1);$i>=0;$i--){
L> $buf = unpack "C", (substr $arg, $i, 1);
L> $value += $buf * (256**($size-$i-1));
L> }
L> return $value;
L> }


much simpler would be to unpack the bytes to an array and then do the
multiply/add stuff in a loop. untested and unfinished:

my @bytes = unpack 'C*, $byte_string ;

my $value ;
for my $byte ( @bytes ) {

multiply/add code
}

uri
 
J

John W. Krahn

Looden said:
Hi
I'm parsing a binary string, which encodes a number.
I don't know the length of the string in advance: 1, 2, 3 or 4 bytes.
The bytes of the string are in network order.
How can I retrieve the number?

I've written this sub, there must be a better way:

sub parse_number {
my $arg = shift;
my $size = length($arg);
my $value = 0;
my $buf;
for (my $i=($size-1);$i>=0;$i--){
$buf = unpack "C", (substr $arg, $i, 1);
$value += $buf * (256**($size-$i-1));
}
return $value;
}

Note: If the length of the string was always 2 bytes, I could just do:
sub parse_n { return unpack "n", shift; }

$ perl -le'
my @strings = ( "\xa", "\xb\x1", "\xc\x2\x3", "\xd\x4\x5\x6" );
for my $string ( @strings ) {
my $number = substr "\0\0\0" . $string, -4;
print unpack "N", $number;
}
'
10
2817
786947
218367238



John
 
O

Oscar Almer

Hi
I'm parsing a binary string, which encodes a number.
I don't know the length of the string in advance: 1, 2, 3 or 4 bytes.
The bytes of the string are in network order.
How can I retrieve the number?

I've written this sub, there must be a better way:

sub parse_number {
my $arg = shift;
my $size = length($arg);
my $value = 0;
my $buf;
for (my $i=($size-1);$i>=0;$i--){
$buf = unpack "C", (substr $arg, $i, 1);
$value += $buf * (256**($size-$i-1));
}
return $value;
}

Note: If the length of the string was always 2 bytes, I could just
do: sub parse_n { return unpack "n", shift; }

Thanks in advance.

I seem to recall (I wrote some code that parses binary strings recently)
that oct() does that, if you prefix it with "0b" to indicate
binaryness. Some application of reverse / substr might be useful to
handle byte ordering.

I could be wrong.

//Oscar
 
U

Uri Guttman

OA> I seem to recall (I wrote some code that parses binary strings
OA> recently) that oct() does that, if you prefix it with "0b" to
OA> indicate binaryness. Some application of reverse / substr might be
OA> useful to handle byte ordering.

OA> I could be wrong.

you are wrong. :)

she has real binary bytes. 0b deals with bits in ascii form.

uri
 
O

Oscar Almer

OA> I could be wrong.

you are wrong. :)

she has real binary bytes. 0b deals with bits in ascii form.

uri

Ah, My bad.

I apologize and retract the previous.

//Oscar
 
S

sln

Hi
I'm parsing a binary string, which encodes a number.
I don't know the length of the string in advance: 1, 2, 3 or 4 bytes.
The bytes of the string are in network order.
How can I retrieve the number?

I've written this sub, there must be a better way:

sub parse_number {
my $arg = shift;
my $size = length($arg);
my $value = 0;
my $buf;
for (my $i=($size-1);$i>=0;$i--){
$buf = unpack "C", (substr $arg, $i, 1);
$value += $buf * (256**($size-$i-1));
}
return $value;
}

Note: If the length of the string was always 2 bytes, I could just do:
sub parse_n { return unpack "n", shift; }

Thanks in advance.

I guess you could also do:

sub parse_number {
my $arg = shift;
vec("\0"x(4-length $arg).$arg, 0, 32);
}

-sln
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top