Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Handling binary

by G109B (Initiate)
on Sep 12, 2015 at 11:54 UTC ( #1141773=perlquestion: print w/replies, xml ) Need Help??

G109B has asked for the wisdom of the Perl Monks concerning the following question:

I guess the answer to my problem lies somewhere in pack/unpack, but I find them very difficult to understand.

I have this string: "139686DA20C1" which represents 48 bits (6 hex bytes). I know that the first 45 bits are my name, written as 9 x 5 bit chars where 00=A to 1A=Z, but I cannot print them without using 'if' cases for each group of 5 bytes (8 chars)

I also need to be able to generate these strings.

Is this the only solution ?

Many thanks

Replies are listed 'Best First'.
Re: Handling binary
by Eily (Monsignor) on Sep 12, 2015 at 14:29 UTC

    pack and unpack are, as a matter of fact a way to achieve what you want although it's not done in one step:
    perl -e 'print join " ", map { chr(ord('A')+eval "0b$_") }  unpack "(A5)*", unpack "B*", pack "H*", "139686DA20C1"'

    The first transformation is pack "H*", $str where the hexadecimal numbers are turned into binary data.

    Then unpack "B*", $str; turns the binary data into a string consisting of the characters '0' and '1'.

    unpack "(A5)*", $str; is one of the many ways to split a string every five characters.

    Then, packing and unpacking those 5 bits strings into numbers would have been possible, but eval "0b$str" just does that in one step.
    chr($nb + ord('A')) is the character at the position "position of A" + $nb. Which is what you want:)

Re: Handling binary
by flexvault (Monsignor) on Sep 12, 2015 at 13:52 UTC

    Welcome G109B,

    I think you will find it easier to use binary strings for your project. To get you started:

    perl -e '$h=pack("H*","139686DA20C1");$b=unpack("B*",$h);print length( +$b)," $b\n";'

    Then use 'substr' to get 5 binary digits at a time.

    while( $b ) { print substr($b,0,5,""); }
    Do the opposite to build your blob.

    Why are you using Base 5, when the rest of the world uses binary?


    "Well done is better than well said." - Benjamin Franklin

Re: Handling binary
by Anonymous Monk on Sep 12, 2015 at 15:26 UTC
    #!/usr/bin/perl # use strict; use warnings; print handlingbinary( "139686DA20C1" ), "\n"; sub handlingbinary { return join '', ('A'..'Z')[ map { oct "0b$_" } (unpack 'B*', pack 'H*', shift()) =~ /.{5}/g ] }



    Hi Colin! (Am I right? If not, let me know :)

      I missed the part about having to generate these strings, here you go:

      #!/usr/bin/perl # use strict; use warnings; my $answer = handlingbinary( "139686DA20C1" ); print "$answer\n"; print tofivebit( 'ANONYMOUS MONK' ), "\n"; print tofivebit( 'COLINWRAY' ), "\n"; sub handlingbinary { return join '', ('A'..'Z')[ map { oct "0b$_" } (unpack 'B*', pack 'H*', shift()) =~ /.{5}/g ] } sub tofivebit { uc unpack 'H*', pack 'B*', shift() =~ tr/A-Z//cdr =~ s/(.)/ sprintf "%05b", ord($1) - ord('A' +) /ger; }

        Many thanks to the three responders, and yes you got it right. The code snippets contain some very welcome insights into this (sometimes) irritating language - at least to an old (retired) C/C++ programmer.

        Why 5 bit ? - not my choice, not my firmware which requires it, but surely to conserve space. There is some 6 bit later in the string because they needed to include digits.

        Hex is a way of life for me.


Re: Handling binary
by Anonymous Monk on Sep 13, 2015 at 22:32 UTC
    You are telling me you don't recognize hexadecimal when you see it?! . . . (kids...)

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1141773]
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2022-05-18 18:38 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (71 votes). Check out past polls.