wwwchinabignet 2011-11-10
有一个业务需求:
根据来访的IP,判断其所属运营商,根据运营商的不同,展示不同的东西。
然后,各种找资料。
刚开始找到一个: 纯真IP。
>>这个··· 首先对制作这个IP数据库的人致敬,但是,数据不符合需求,因为,我们需要运营商。
然后又找到一个: APNIC。
>>这个··· 由于linux中已经提供了相关的命令--whois(没有提供的可以自己安装,到apnic的网站上下载就行,不叙),
>>所以,就像很多其他文章(google:apnic whois 运营商)中说的似的,貌似,编写个脚本,分析一下数据,就可以得
>>到各运营商的IP段,但是,whois返回的详细信息太不规范,用这种狗血的信息分析,无疑是自杀。
>>再者,中国的运营商,那叫一个乱起八糟,不说了···
然后又找到一个:ip138。
>>仔细看了一下,这个网站查询出的东西,挺准确的,要不自己写个抓取程序?嗯,先试试吧···
------------------------------华丽丽---------------------------------
最终还是选择了权威的APNIC
从这个网页上可以找到中国的IP段(网页上给出了提示,说可能不是很全、很新····不过,凑合着用吧):http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest
附上此网页中数据的说明:
1、在网页中查找“|CN|ipv4|”,匹配的行即为天朝IP地址段信息。
2、拿其中一条数据做说明,比如这条:
apnic|CN|ipv4|60.55.0.0|65536|20040802|allocated
我们看以“|”做区分后的第四个和第五个值,即:60.55.0.0和65536。其他的值可以不用管了
这两个值组合起来其实可以这么表示:60.55.0.0/16,这种方式叫CIDR,表示的是一个网段,我也一知半解的,
这里就不多说了,对于网络基础一般的童鞋来说,就可以这样理解:从60.55.0.0,后面65536个IP都是这个网段
的,这就够了。
那么可以开始了,先是写一个shell,去读取这个网页,然后调用whois,分析返回回来的字符串,判断IP段所属运营商。
#!/bin/sh DIR=/data/ip APNIC=$DIR/apnic CNNET=$DIR/cnnet ctc=$DIR/ctc cucc=$DIR/cucc cmcc=$DIR/cmcc rm -f $APNIC rm -f $CNNET rm -f $ctc rm -f $cucc rm -f $cmcc wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest -O $APNIC grep '|CN|ipv4|' $APNIC | cut -f 4,5 -d'|'|sed -e 's/|/ /g' | while read ip submask do echo $ip/$submask echo $ip/$submask >> $CNNET NETNAME=`whois $ip | grep -e ^netname -e ^mnt-by -e ^mnt-lower -e ^descr | sed -e 's/.*: (.*)/1/g' | sed -e 's/-.*//g'` if echo $NETNAME | grep -i -e 'CHINANET' -e 'CHINATELECOM' then echo $ip/$submask >> $ctc elif echo $NETNAME | grep -i -e 'UNICOM' -e 'CNC' -e 'CNCGROUP' then echo $ip/$submask >> $cucc elif echo $NETNAME | grep -i -e 'CMNET' -e 'CMCC' -e 'MOBILE' then echo $ip/$submask >> $cmcc fi done
这样,执行完这个shell后,不同的运营商IP信息就在相应的文件中了。
然后,从写一个java程序,去读取上面的文件,然后根据实际情况处理就行了。
下面贴出最主要的代码:
long f = Utils.ip2Long(from); // from 即上面的60.55.0.0 long t = f + Long.parseLong(count) - 1; // count 即上面的65536 // 下面贴出IP的字符串和长整型相互转换的方法 /** * 将形如127.0.0.1的IP转换为其所对应的长整型数值 * 说明: * 无任何校验及异常捕获,请传入正确的IP字符串 */ public static long ip2Long(String ipStr) { long[] ipLong = new long[4]; String[] off = ipStr.split("\\."); ipLong[0] = Long.parseLong(off[0]) << 24; ipLong[1] = Long.parseLong(off[1]) << 16; ipLong[2] = Long.parseLong(off[2]) << 8; ipLong[3] = Long.parseLong(off[3]); return ipLong[0] + ipLong[1] + ipLong[2] + ipLong[3]; } /** * 将长整型数值的IP转换为其所对应的形如127.0.0.1的字符串 * 说明: * 无任何校验及异常捕获,请传入正确的IP长整数 */ public static String long2Ip(long ipLong) { StringBuilder ip = new StringBuilder(); ip.append(ipLong >>> 24).append("."); ip.append((ipLong & 0x00FFFFFF) >>> 16).append("."); ip.append((ipLong & 0x0000FFFF) >>> 8).append("."); ip.append((ipLong & 0x000000FF)); return ip.toString(); }
网上闲逛,看到一个java调用whois的程序,用了apache commons 的 net 包,强大的apache!