为了跟第三方监控做对比和作为备用,准备自己通过页面js返回数据做个监控。首先第一步,整理一个足够自己用的ip库。 首先,考虑调用会比较频繁,打算把内容尽可能归并,到省级运营商即可; 其次,未知归并完会有多大的情况下,考虑到qqwry的地区都是中文,打算统一使用电话区号代替地区,运营商也有一位数字代替,ip采用inet-aton网络值代替;这样每条记录的字节数固定,可以方便采用seek和sysread提高读取某条记录的速度。
前几步工作和之前整理ip库给dns用的时候一样,导出qqwry.txt,约42w条,24MB大小。
然后从网上搜一下全国电话区号,以各省省会(首府)的区号为准,存成一个quhao.txt,为了之后处理方便,只保留前两个中文,好在中国的省份里也只有内蒙古和黑龙江是三个字,留两位不至于影响阅读,txt内容如下:
yaml北京 0010
上海 0021
天津 0022
重庆 0023
安徽 0551
福建 0591
甘肃 0931
广东 0020
广西 0771
贵州 0851
海南 0898
河北 0311
河南 0371
黑龙 0451
湖北 0027
湖南 0731
吉林 0431
江苏 0025
江西 0791
辽宁 0024
内蒙 0471
宁夏 0951
青海 0971
山东 0531
山西 0351
陕西 0029
四川 0028
西藏 0891
新疆 0991
云南 0871
浙江 0571
然后用如下perl脚本归并:
use strict;
use warnings;
my($quhao, $qqwry) = @ARGV;
$code = read_area_code($quhao);
overwrite_iplist($qqwry, $code);
sub inet_aton {
my $ip = shift;
my $short = sprintf "%010s", $1 * 256**3 + $2 * 256**2 + $3 * 256 + $4 if $ip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
return $short;
};
sub read_area_code {
my $file = shift;
my $area_code = {};
open my $fh,'<',"$file" or die "Cannot open $file";
while (<$fh>) {
chomp;
my($area,$code) = split;
$area_code->{"$area"} = "$code";
}
close $fh;
return $area_code;
};
sub overwrite_iplist {
my($iplist, $area_code) = @_;
my($last_begin_ip_n, $last_end_ip_n, $last_province_n, $last_isp_n);
open my $fh,'<',"$iplist" or die "Cannoet open $iplist";
while (<$fh>) {
chomp;
my($begin_ip, $end_ip, $area, $isp) = split;
my($province_n, $isp_n);
my $begin_ip_n = &inet_aton("$begin_ip");
my $end_ip_n = &inet_aton("$end_ip");
next if ($end_ip_n - $begin_ip_n) < 32;
if ( $area =~ /学/ ) {
$isp_n = 4; #教育网, 因为清华北大等学校记录在area里了,所以这步提前设定
};
if ( $isp =~ m/电信/ ) {
$isp_n = 1; #电信
} elsif ( $isp =~ m/联通/ ) {
$isp_n = 2; #联通(包括原网通)
} elsif ( $isp =~ m/铁通|移动/ ) {
$isp_n = 3; #移动(包括原铁通)
} elsif ( $isp =~ m/学/ ) {
$isp_n = 4; #教育网
} else {
$isp_n = 0; #国外地址及其他未能识别的国内运营商
};
my $province = substr($area, 0, 4); #中文用2字节,所以对原始记录获取前四字节即为省份名
if ( exists $area_code->{"$province"} ) {
$province_n = $area_code->{"$province"}; #国内已知电话区号的省份
} else {
$province_n = '0000'; #港澳台及外国,可能有其他未能识别的国内地址
};
#下段为合并网段,之前dns时也用过
if (!$last_province_n) {
($last_begin_ip_n, $last_end_ip_n, $last_province_n, $last_isp_n) = ($begin_ip_n, $end_ip_n, $province_n, $isp_n);
};
if ( $last_province_n == $province_n && $last_isp_n == $isp_n ) {
$last_end_ip_n = $end_ip_n;
} else {
printf "%010s %010s %04s %s\n", $last_begin_ip_n, $last_end_ip_n, $last_province_n, $last_isp_n;
($last_begin_ip_n, $last_end_ip_n, $last_province_n, $last_isp_n) = ($begin_ip_n, $end_ip_n, $province_n, $isp_n);
};
};
close $fh;
};
最后运行如下命令即可获得精简ip库:
bashperl overwrite.pl quhao.txt qqwry.txt > newip.txt
对比一下大小和行数:
bash[root@cdn2 ~]# ll
-rw-r--r-- 1 root root 539226 Jul 25 18:18 newer.txt
-rw-r--r-- 1 root root 9058928 May 15 13:13 QQWry.dat
-rw-r--r-- 1 root root 24753935 Jul 25 15:26 qqwry.txt
-rw-r--r-- 1 root root 340 Jul 25 15:03 quhao.txt
-rw-r--r-- 1 root root 2439 Jul 25 18:17 test.pl
[root@cdn2 ~]# wc -l *
18594 newer.txt
34727 QQWry.dat
428454 qqwry.txt
30 quhao.txt
72 test.pl
好了,一天一天来,明天实现在这527KB的文件里快速定位ip……