Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

while loop on binary : \x30

by sphalaris (Novice)
on May 16, 2016 at 16:33 UTC ( [id://1163145]=perlquestion: print w/replies, xml ) Need Help??

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

O munificent ones!
I've been working with binary strings, which, coming from an image file, can have any bin-value. The following behaviour caused a lot of head scratching till I found out where the problem was:
my @strings=("ab30ff","30","ab1a30"); for (@strings){ $_=pack ("H*",$_); } for my $b1 (@strings){ print "here: "; while ($b1){ my $b1=substr $b1,0,1,""; my $bits=unpack ("B*",$b1); print "$bits//"; } print "\n"; } here: 10101011//00110000//11111111// here: here: 10101011//00011010//
As you can see, if \x30 comes at the end of the string or the string only consists of \x30, "while" breaks off. The strings come from a read-in filehandle, which was in binmode, but have been extracted and passed between subs. Is there any way to force "while" to treat it as binary here.
All suggestions gratefully received

Replies are listed 'Best First'.
Re: while loop on binary : \x30
by Corion (Patriarch) on May 16, 2016 at 16:44 UTC
    perl -wle "print qq(\x30)" 0

    The while statement takes an expression and looks at it in terms of Perly truthiness. The strings '' and '0' are false in boolean context for Perl.

    Most likely, you simply want to check for the length of your string while removing things from it.

Re: while loop on binary : \x30
by AnomalousMonk (Archbishop) on May 16, 2016 at 20:49 UTC

    Another approach:

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my @strings = map pack('H*', $_), '30abff', 'ab30ff', '30', 'ab1a30'; dd \@strings; ;; for my $bs (@strings) { printf 'here: '; my @bits = unpack '(B8)*', $bs; print join '//', @bits; } " ["0\xAB\xFF", "\xAB0\xFF", 0, "\xAB\x1A0"] here: 00110000//10101011//11111111 here: 10101011//00110000//11111111 here: 00110000 here: 10101011//00011010//00110000
    Please see pack, unpack, perlpacktut.

    Update: Added another example string:  '30abff'


    Give a man a fish:  <%-{-{-{-<

Re: while loop on binary : \x30
by Marshall (Canon) on May 16, 2016 at 19:14 UTC
    I hope that this can help clarify things... The issue is whether you have a string or a number. A couple of demo's:
    #!/usr/bin/perl use warnings; use strict; #prints "0" becaus 0x30 is "0" in ASCII my $char = "\x30"; #quotes makes $char a "character" # result being the number "0" in ASCII # which translates to numeric 0! print "$char\n"; #prints "0" printf "%08b\n", $char; #still prints "0"!! print "\nNow, 0x30 as a number, not a character\n"; #without the quotes, we have a binary number... my $char2 = 0x30; print "$char2\n"; #prints 48 (decimal 0x30) printf "%08b\n", $char2; #prints "00110000" __END__ 0 00000000 Now, 0x30 as a number, not a character 48 00110000
    Sometimes the hex function can be useful.
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my @strings=("ab30ff","30","ab1a30"); for (@strings){ $_=hex $_; } foreach my $hex (@strings) { printf "%08b\n", $hex; } __END__ 101010110011000011111111 00110000 101010110001101000110000
Re: while loop on binary : \x30
by marioroy (Prior) on May 17, 2016 at 00:55 UTC

    Update: Adding use bytes at the top of the script does not work. I thought that this would help.

    At the top of your script, load bytes.

    use bytes;

    Though, the Perl doc states the use of this module for anything other than debugging purposes is strongly discouraged.

Re: while loop on binary : \x30
by sphalaris (Novice) on May 17, 2016 at 06:14 UTC
    Many thanks for the prompt replies.
    Yes, I can avoid a "while" loop by using "split", and that solves the problem as far as my script goes. Hopefully, I must say, because as someone said in these pages once, dealing with binary data can cause acute pains in the head.
    I notice that it doesn't have to be a binary string: a simple text string ending in a zero, or consisting only of a zero will not make the character available in the while loop. This is for me in certain contexts a problem. For the future I must avoid using 'while' to munch a string.
Re: while loop on binary : \x30
by sphalaris (Novice) on May 17, 2016 at 17:16 UTC
    beech - thanks. Corion at the top suggested the same but the penny didn't drop with me until I saw your implementation.
    So "while" is possible.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (4)
As of 2024-04-19 22:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found