Perl побитовый И дает мне интересные результаты - PullRequest
8 голосов
/ 20 сентября 2011

Я пишу небольшой Perl-скрипт для сравнения двух IP-адресов с помощью побитового оператора И perls.но я получаю некоторые действительно интересные результаты.Я новичок в Perl, так что, возможно, кто-то может дать мне несколько советов.

Вот мой маленький сценарий:

#!/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 & 255, "\n";
print 12 & 255, "\n";
print 0 & 0, "\n";

Кто-нибудь знает, почему или как я получил "050 24 00 0", когдаделать побитовое И для членов $ octets и $ octets2?Кажется, что все работает нормально, когда я делаю побитовый И с использованием литераловПожалуйста помоги.Спасибо!

Ответы [ 5 ]

13 голосов
/ 20 сентября 2011

Битовые операции действуют по-разному для строк и чисел, а split возвращает строки.Преобразуйте строки в числа, используя 0+ или 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";
6 голосов
/ 20 сентября 2011

Если вы не собираетесь использовать модуль CPAN, такой как Net :: IP или Net :: Netmask, по крайней мере, используйте некоторые из предоставленных вам инструментов:

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";

или, более кратко, просто:

use Socket;
print inet_ntoa(
  inet_aton("127.34.12.123") 
  & inet_aton("255.255.255.0") 
), "\n";
6 голосов
/ 20 сентября 2011

Я предлагаю вам использовать CPAN-модуль, такой как Net :: IP.

Также всегда ставьте use strict;использовать предупреждения;в верхней части вашей программы.

5 голосов
/ 20 сентября 2011

Вот милая быстрая версия:

my $address  = 172.34.12.0;
my $address2 = 255.255.255.0;
my @a = map ord, split //, $address & $address2;
say for @a;

Чтобы преодолеть строковые v-строки:

my $address  = eval "172.34.12.0";
my $address2 = eval "255.255.255.0";
4 голосов
/ 20 сентября 2011

Вы не конвертировали в числа.Вы встречаете персонажей друг с другом.

...