extract number from binary string

Discussion in 'Perl Misc' started by Looden, Mar 1, 2010.

  1. Looden

    Looden Guest

    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.
     
    Looden, Mar 1, 2010
    #1
    1. Advertisements

  2. Looden

    Uri Guttman Guest

    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
     
    Uri Guttman, Mar 1, 2010
    #2
    1. Advertisements

  3. $ 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
     
    John W. Krahn, Mar 1, 2010
    #3
  4. Looden

    Oscar Almer Guest

    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
     
    Oscar Almer, Mar 1, 2010
    #4
  5. Looden

    Uri Guttman Guest

    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
     
    Uri Guttman, Mar 1, 2010
    #5
  6. Looden

    Oscar Almer Guest

    Ah, My bad.

    I apologize and retract the previous.

    //Oscar
     
    Oscar Almer, Mar 1, 2010
    #6
  7. Looden

    sln Guest

    I guess you could also do:

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

    -sln
     
    sln, Mar 1, 2010
    #7
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.