Perl bitwise AND giving me funky results
I am writing a little perl script to compare two IP addresses using perls bitwise AND operator. but I am getting some really funky results. I'm new to perl so maybe someone can give me a few pointers.
Heres my little script:
#!/usr/bin/perl
$address = "172.34.12.0";
$address2 = "255.255.255.0";
@octets = split (/\./,$address);
@octets2 = split (/\./,$address2);
#Funky results when doing a bitwise AND
#This outputs "050 24 00 0" What's going on here?
print $octets[0] & $octets2[0], "\n";
print $octets[1] & $octets2[1], "\n";
print $octets[2] & $octets2[2], "\n";
print $octets[3] & $octets2[3], "\n";
#Results are what I want when doing it as literals
#This outputs "172 34 12 0"
print 172 & 255, "\n";
print 34 &开发者_如何学Goamp; 255, "\n";
print 12 & 255, "\n";
print 0 & 0, "\n";
Anyone know why or how I got "050 24 00 0" when doing the bitwise AND on the $octets and $octets2 members? Everything seems to work just fine when I do the bitwise AND using literals. Please help. Thanks!
The bitwise ops act different on strings and numbers, and split
returns strings. Convert the strings to numbers using 0+
or int
. http://codepad.org/sqHntIgZ:
#!/usr/bin/perl
$address = "172.34.12.0";
$address2 = "255.255.255.0";
@octets = split (/\./,$address);
@octets2 = split (/\./,$address2);
#Funky results when doing a bitwise AND
#This outputs "050 24 00 0" What's going on here?
print int($octets[0]) & int($octets2[0]), "\n";
print int($octets[1]) & int($octets2[1]), "\n";
print int($octets[2]) & int($octets2[2]), "\n";
print int($octets[3]) & int($octets2[3]), "\n";
#Results are what I want when doing it as literals
#This outputs "172 34 12 0"
print 172 & 255, "\n";
print 34 & 255, "\n";
print 12 & 255, "\n";
print 0 & 0, "\n";
I suggest that you use a CPAN module such as Net::IP.
Also always put use strict; use warnings; at the top of your program.
If you're not going to use a CPAN module like Net::IP or Net::Netmask, at least use some of the tools given to you:
use strict;
use warnings;
use Socket;
my $address = "172.34.12.123";
my $address2 = "255.255.255.0";
my $raw_masked = inet_aton($address) & inet_aton($address2);
my $masked = inet_ntoa($raw_masked);
print $masked, "\n";
or more tersely, simply:
use Socket;
print inet_ntoa(
inet_aton("127.34.12.123")
& inet_aton("255.255.255.0")
), "\n";
Here's a cute fast version:
my $address = 172.34.12.0;
my $address2 = 255.255.255.0;
my @a = map ord, split //, $address & $address2;
say for @a;
To overcome stringified v-strings:
my $address = eval "172.34.12.0";
my $address2 = eval "255.255.255.0";
You didn't convert to numbers. You're ANDing characters with each other.
精彩评论