Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Unpacking variable length bit fields

by BrowserUk (Patriarch)
on Jun 18, 2012 at 20:58 UTC ( [id://976900]=note: print w/replies, xml ) Need Help??


in reply to Unpacking variable length bit fields

Assuming your bitfields are all multiples of 8, then using unpack's length/type nomenclature will work.

$bitstream = "\x18\xf0\xff\x0f\x10\xaa\x55\x20\xde\xad\xbe\xef";; ( $f1, $f2, $f3 ) = unpack 'C/b C/b c/B', $bitstream;; print for $f1, $f2, $f3;; 000011111111111111110000 0101010110101010 11011110101011011011111011101111
You'll need to use the correct variations of 'c' or 'C' (probably the latter) and b/B (which will depend upon the endianess of the originating hardware. I've used a mixture here to demonstrate the affect of some of the combinations.

Note also that the output is ascii-ised binary. That is, each bit of the input is translated to a byte containing ascii '0' or ascii '1'.

Other variations are possible. For example, you might want to retain the bits as binary encoded fields and then manipulate them with vec. But you'd need to explain more about what they are.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?

Replies are listed 'Best First'.
Re^2: Unpacking variable length bit fields
by puterboy (Scribe) on Jun 19, 2012 at 04:15 UTC
    Oops, I spoke to soon. The field length specifies the number of bits (multiple of 8) but I want to extract the fields themselves as bytes not as bit strings of 1/0's.

    My problems is that using something like: unpack('C/C'...) would unpack C bytes for each filed rather than C bits for each field which is what I want. So I really would like to divide by 8 but I'm not sure how to do that. I imagine I could unpack as a bit string of 1/0's then split, then repack but that seems klugey.

    It's a screwy format, but I don't have control over it....

      The the easiest way is to convert the ascii-ised binary back to real numbers:

      $bitstream = "\x18\xf0\xff\x0f\x10\xaa\x55\x20\xde\xad\xbe\xef";; ( $f1, $f2, $f3 ) = map unpack( 'L', pack( 'b32', $_ )), unpack 'C/b C +/b C/b', $bitstream;; print for $f1, $f2, $f3;; 1048560 21930 4022250974

      This assumes maximum 32-bit values. You could use Q if you are on a 64-bit platform and Perl and need that.

      By converting them all to the maximum sized integer the platform can handle you save having to make decisions and they'd end up that way anyway.

      You might need to adjust the L (or the 'b32' to 'B32' or 'B64') for the endianness of the originating platform.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

Re^2: Unpacking variable length bit fields
by puterboy (Scribe) on Jun 18, 2012 at 22:58 UTC
    This appears to be EXACTLY what I needed. Thanks!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://976900]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-23 17:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found