matching the network segment but can't work :-(

F

Facco Eloelo

I have a network segment list in a text file called IPsegment.txt,it looks like
this:

IPsegment.txt
219.111.192.0/18
68.132.0.0/17
67.146.0.0/16
192.162.0.0/16
152.172.0.0/16
34.132.0.0/14
97.208.0.0/13


And I have some IP addresses in another text file called IPlist.txt.It looks
like this:

IPlist.txt
www.yahoo.com,66.94.230.51
www.baidu.com,202.108.250.249
www.sina.com.cn,61.135.152.77
www.sohu.com,61.135.150.75
....

Now,I want to know whether the IP addresses in the IPlist.txt belongs the
network segment writen in the IPsegment.txt.
The mathing IP list is outputed into a new text file called matchinglist.txt.
It looks like this:

matchinglist.txt
www.baidu.com,202.108.250.249
www.sina.com.cn,61.135.152.77
....


This is what I code:
It doesn't work. :-(
can anyone help me fix it?I'm a perl newbie.thanks.


#!/usr/bin/perl
my %ip;
open FH,'<','d:\a\IPSegment.txt';
while (<FH>) {
chomp($_);
$ip{$_}=0;
}
close FH;

open FH,'<','d:\a\IPList.txt';
open FH2,'>>','d:\a\Matchlist.txt';
while (<FH>) {
chomp ($_);
$rec=$_;
($domain, $domip) = split(/,/, $_);
if ($ip{'$domip'} > 0) {
print FH2 $rec,"\n";
$ip{'$domip'}++; #increment a counter here, output from hash
}
}
close FH;
close FH2;
 
P

Paul Lalli

I have a network segment list in a text file called IPsegment.txt,it looks like
this:

IPsegment.txt
219.111.192.0/18
68.132.0.0/17
67.146.0.0/16
192.162.0.0/16
152.172.0.0/16
34.132.0.0/14
97.208.0.0/13


And I have some IP addresses in another text file called IPlist.txt.It looks
like this:

IPlist.txt
www.yahoo.com,66.94.230.51
www.baidu.com,202.108.250.249
www.sina.com.cn,61.135.152.77
www.sohu.com,61.135.150.75
...

Now,I want to know whether the IP addresses in the IPlist.txt belongs the
network segment writen in the IPsegment.txt.
The mathing IP list is outputed into a new text file called matchinglist.txt.
It looks like this:

matchinglist.txt
www.baidu.com,202.108.250.249
www.sina.com.cn,61.135.152.77
...


This is what I code:
It doesn't work. :-(

This is not a good problem statement. When posting to this group, you
should always state *how* it doesn't work. What it does or doesn't do
that you didn't expect.
can anyone help me fix it?I'm a perl newbie.thanks.


#!/usr/bin/perl

add the statements
use strict;
use warnings;

to receive the maximal help from this group with the minimal complaining.
my %ip;
open FH,'<','d:\a\IPSegment.txt';

Always check the return value of open. In this case, you have no way of
knowing if the file actually opened.

open FH, '<', 'D:\a\IPSegment.txt' or die "Could not open Segments: $!";
while (<FH>) {
chomp($_);
$ip{$_}=0;
}
close FH;

open FH,'<','d:\a\IPList.txt';
open FH2,'>>','d:\a\Matchlist.txt';

see above.
while (<FH>) {
chomp ($_);
$rec=$_;

These three statements could be combined into one:

while (chomp ($rec= said:
($domain, $domip) = split(/,/, $_);
if ($ip{'$domip'} > 0) {

And here's at least one problem. By putting $domip in single quotes,
you're checking the value of the hash at the literal string '$domip', not
the value of the variable $domip. Remove those quotes.
print FH2 $rec,"\n";
$ip{'$domip'}++; #increment a counter here, output from hash
}

And here's the second problem. (First, again remove the quotes). You're
only incrementing the value of the hash key if it's already greater than
0. This can't happen, since you initially set each position to 0. This
statement needs to be taken out of the if block.

What you really need to check is to see whether or not the IP address
already exists in your hash, and if it does, increment the count and print
it out.

Rewrite the if block as follows:

$ip{$domip}++ if exists $ip{$domip};
if ($ip{$domip} == 1) { #only want to add to the output file once!
print FH2 "$rec\n";
}
}
close FH;
close FH2;

HTH,
Paul Lalli
 
J

Joe Smith

Facco said:
open FH,'<','d:\a\IPSegment.txt';
while (<FH>) {
chomp($_);
$ip{$_}=0;
}

You are not doing anything with the number after the '/', and you should.
219.111.192.0/18

That one specification translates into 16384 individual IP addresses.

$ip{'219.111.192.0'} = 0;
$ip{'219.111.192.1'} = 0;
$ip{'219.111.192.2'} = 0;
$ip{'219.111.192.3'} = 0;
...
$ip{'219.111.223.252'} = 0;
$ip{'219.111.223.253'} = 0;
$ip{'219.111.223.254'} = 0;
$ip{'219.111.223.255'} = 0;
if ($ip{'$domip'} > 0) {
print FH2 $rec,"\n";
$ip{'$domip'}++; #increment a counter here, output from hash
}

I would use one line for that: [No single quotes around hash keys!]
print FH2 $rec,"\n" if $ip{$domip}++; # Print duplicates after first

####################################################################

As for your segments, this may be helpful:

linux% cat temp.pl
use strict; use warnings;
use Socket;

my @data = qw( 219.111.192.0/18 68.132.0.0/17 67.146.0.0/16 192.162.0.0/16
152.172.0.0/16 34.132.0.0/14 97.208.0.0/13 128.0.0.0/16 );

sub cidr {
my($base,$bits) = split '/',$_[0]; # Assumes that $base really lowest
my $ip4 = sprintf "%u",(unpack "N",inet_aton $base);
( $ip4, $ip4 + 2**(32-$bits)-1 ); # Return low and high
}

foreach my $segment (@data) {
my($lo,$hi) = cidr($segment);
printf "%17s = %10s .. %10s (%8x to %8x)\n", $segment, $lo, $hi, $lo, $hi;
}

linux% perl temp.pl
219.111.192.0/18 = 3681533952 .. 3681550335 (db6fc000 to db6fffff)
68.132.0.0/17 = 1149501440 .. 1149534207 (44840000 to 44847fff)
67.146.0.0/16 = 1133641728 .. 1133707263 (43920000 to 4392ffff)
192.162.0.0/16 = 3231842304 .. 3231907839 (c0a20000 to c0a2ffff)
152.172.0.0/16 = 2561409024 .. 2561474559 (98ac0000 to 98acffff)
34.132.0.0/14 = 579076096 .. 579338239 (22840000 to 2287ffff)
97.208.0.0/13 = 1641021440 .. 1641545727 (61d00000 to 61d7ffff)
128.0.0.0/16 = 2147483648 .. 2147549183 (80000000 to 8000ffff)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top