- 浏览: 21768 次
- 性别:
- 来自: 青岛
最近访客 更多访客>>
最新评论
-
Hooopo:
既然纯真数据库数据比PHPwind精确,何不用纯真?按照楼主分 ...
IPParse: IP 地址查询 -
wosmvp:
convert_ip_format.rb,不是BUG,指特殊或 ...
IPParse: IP 地址查询 -
Hooopo:
看了你分割后的文件,其他都是ip段的第一个字段做文件名,但是有 ...
IPParse: IP 地址查询 -
Hooopo:
<div class="quote_title ...
IPParse: IP 地址查询 -
jiyanliang:
js好像不能直接操作文件
js 下载文件
1)在shell中:
$ ipparse 218.58.88.175 212.1.1.1 192.245.148.0 116.254.254.0
218.58.88.175 => 山东省青岛市开发区
212.1.1.1 => 意大利
192.245.148.0 => 阿尔及利亚
116.254.254.0 => 广东省广州市
2)程序中:
require ‘rubygems’
require ‘ipparse’
IPParse.parse(‘218.58.88.175’) # => 山东省青岛市开发区
有效代码30多行,使用了PHPWind的IP数据库(稍稍改了改格式,源码里提供了工具)
分析10000个随机IP 需要5秒左右的时间
地址:http://github.com/wosmvp/ipparse/tree/master
安装:(申请了RubyForge ipparse 目前还没有审核)
$ git clone git://github.com/wosmvp/ipparse.git
$ cd ipparse
$ rake install (可能需要安装 echoe )
------
http://www.zhangjinzhu.com
工具在哪里?
嗯,我说的UNKNOW不是你说的UNKNOW的意思,是测试跑不过的意思,
格式化文件,我提供了一个里面提供了一个脚本,win下去掉第一行,跑跑应该可以的正确得到格式的
现在修改你的代码 raise 为return false测试全过了,程序应该可以跑出正确结果了
我从你发帖时写的那个地址下的data文件,不知道你后来改了没。0.txt里本身就有很多Unknown,不过大小写不一样。而且每个文件开头都有一段空白,split会出问题,我删掉了。我也没测试,刚把randip分析的结果输出到文件里看了下,是有几个没找到。好像每个文件第一条记录都没有分析出来,我再看看。那个benchmark我就随便写着看看时间,无所谓那么精确了。profile了下,主要都是IO#each消耗的时间。如果没有那个data缓存,估计会慢很多。
谢谢,已合并,性能又提升了0.*秒
分开写没有感觉到性能的提升,并且代码量也会多一些
另外你提供使用Benchmark做性能测试结果会存在偏差,因为里面包含ips.each的时间,10万次差不多也要花 0.0* 秒
$ ipparse 218.58.88.175 212.1.1.1 192.245.148.0 116.254.254.0
218.58.88.175 => 山东省青岛市开发区
212.1.1.1 => 意大利
192.245.148.0 => 阿尔及利亚
116.254.254.0 => 广东省广州市
2)程序中:
require ‘rubygems’
require ‘ipparse’
IPParse.parse(‘218.58.88.175’) # => 山东省青岛市开发区
有效代码30多行,使用了PHPWind的IP数据库(稍稍改了改格式,源码里提供了工具)
分析10000个随机IP 需要5秒左右的时间
地址:http://github.com/wosmvp/ipparse/tree/master
安装:(申请了RubyForge ipparse 目前还没有审核)
$ git clone git://github.com/wosmvp/ipparse.git
$ cd ipparse
$ rake install (可能需要安装 echoe )
------
http://www.zhangjinzhu.com
评论
37 楼
Hooopo
2009-08-24
既然纯真数据库数据比PHPwind精确,何不用纯真?按照楼主分割数据的方式和纯真数据库自带的导出txt工具,写了个分割脚本:
PS:顺便问下快客王和楼上几位说的用纯真数据库一次加载到内存是如何做的?是用的orlaa提供的代码还是自己写的?再做下性能测试。。
require 'iconv' #编码转换 def utf8(str) Iconv.conv("UTF-8", "GBK", str) end #获取ip地址前面字段 def get_first_num(str) str =~ /(\d{0,3})\./ ? $1 : nil end #格式化多余空格 def drop_white_space(str) str.gsub(/\s+\b/, " ") end #转化成192.168.000.001的格式 def add_zero(str) str.gsub(/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/) do |ip| ip.gsub(/(\d{1,3})/){|m| m.rjust(3,"0")} end end #分割成多个文件 File.open("QQwry.txt","r") do |file| file.each_line do |line| File.open("#{get_first_num(line)}.txt", "a") do |f| f.write(add_zero(utf8(drop_white_space(line)))) end end end
PS:顺便问下快客王和楼上几位说的用纯真数据库一次加载到内存是如何做的?是用的orlaa提供的代码还是自己写的?再做下性能测试。。
36 楼
wosmvp
2009-08-22
convert_ip_format.rb,
不是BUG,指特殊或其它文件中不存在的IP
不是BUG,指特殊或其它文件中不存在的IP
35 楼
Hooopo
2009-08-21
看了你分割后的文件,其他都是ip段的第一个字段做文件名,但是有一个0.txt里面内容很乱,这个是bug吗?还是?
引用
000.000.000.000 001.051.255.255 IANA
001.052.000.000 001.052.255.255 美国
001.053.000.000 001.153.255.255 IANA
001.154.000.000 001.154.255.255 美国
001.155.000.000 002.255.255.255 IANA
003.000.000.000 004.255.255.255 美国
005.000.000.000 005.147.255.255 IANA
005.148.000.000 005.148.255.255 加拿大
005.149.000.000 005.255.255.255 IANA
006.000.000.000 009.255.255.255 美国
010.000.000.000 010.255.255.255 局域网
011.000.000.000 021.233.255.255 美国
021.234.000.000 021.234.255.255 台湾省
021.235.000.000 022.255.255.255 美国
023.000.000.000 023.031.255.255 IANA
023.032.000.000 023.032.255.255 美国
023.033.000.000 023.123.255.255 IANA
023.124.000.000 023.124.255.255 美国
023.125.000.000 023.189.255.255 IANA
023.190.000.000 023.190.255.255 美国
023.191.000.000 023.255.255.255 IANA
024.000.000.000 024.035.127.255 美国
024.035.128.000 024.037.255.255 加拿大
024.038.000.000 024.038.015.255 美国
024.038.016.000 024.038.159.255 加拿大
024.038.160.000 024.038.175.255 美国
024.038.176.000 024.038.191.255 加拿大
024.038.192.000 024.038.223.255 美国
024.038.224.000 024.038.255.255 加拿大
024.039.000.000 024.039.127.255 美国
024.039.128.000 024.039.255.255 加拿大
024.040.000.000 024.040.079.255 美国
024.040.080.000 024.040.095.255 加拿大
024.040.096.000 024.040.111.255 美国
024.040.112.000 024.040.255.255 加拿大
024.041.000.000 024.041.095.255 美国
024.041.096.000 024.043.255.255 加拿大
024.044.000.000 024.056.255.255 美国
024.057.000.000 024.057.255.255 加拿大
024.058.000.000 024.063.255.255 美国
024.064.000.000 024.072.143.255 加拿大
024.072.144.000 024.075.255.255 美国
024.076.000.000 024.087.255.255 加拿大
024.088.000.000 024.089.031.255 美国
024.089.032.000 024.089.063.255 Unknown
024.089.064.000 024.089.127.255 加拿大
024.089.128.000 024.089.191.255 美国
024.089.192.000 024.089.255.255 加拿大
024.090.000.000 024.099.255.255 美国
024.100.000.000 024.103.255.255 加拿大
024.104.000.000 024.107.255.255 美国
024.108.000.000 024.109.255.255 加拿大
024.110.000.000 024.110.255.255 美国
024.111.000.000 024.112.255.255 加拿大
024.113.000.000 024.113.191.255 美国
024.113.192.000 024.114.255.255 加拿大
024.115.000.000 024.121.255.255 美国
024.122.000.000 024.122.255.255 加拿大
024.123.000.000 024.129.223.255 美国
024.129.224.000 024.129.239.255 加拿大
024.129.240.000 024.129.255.255 Unknown
024.130.000.000 024.131.255.255 美国
024.132.000.000 024.135.255.255 荷兰
024.136.000.000 024.137.031.255 美国
024.137.032.000 024.137.047.255 加拿大
024.137.048.000 024.137.063.255 Unknown
024.137.064.000 024.137.127.255 加拿大
024.137.128.000 024.137.191.255 美国
024.137.192.000 024.137.223.255 加拿大
024.137.224.000 024.137.255.255 Unknown
024.138.000.000 024.138.079.255 加拿大
024.138.080.000 024.138.095.255 Unknown
024.138.096.000 024.138.111.255 加拿大
024.138.112.000 024.138.127.255 Unknown
024.138.128.000 024.138.191.255 加拿大
024.138.192.000 024.138.255.255 波多黎各
024.139.000.000 024.139.031.255 加拿大
024.139.032.000 024.139.063.255 Unknown
024.139.064.000 024.139.095.255 波多黎各
024.139.096.000 024.139.127.255 Unknown
024.139.128.000 024.139.223.255 波多黎各
024.139.224.000 024.139.255.255 Unknown
024.140.000.000 024.140.255.255 美国
024.141.000.000 024.141.255.255 加拿大
024.142.000.000 024.143.047.255 美国
024.143.048.000 024.143.063.255 加拿大
024.143.064.000 024.143.095.255 美国
024.143.096.000 024.143.127.255 加拿大
024.143.128.000 024.143.175.255 美国
024.143.176.000 024.143.223.255 加拿大
024.143.224.000 024.145.255.255 美国
024.146.000.000 024.146.255.255 加拿大
024.147.000.000 024.149.031.255 美国
001.052.000.000 001.052.255.255 美国
001.053.000.000 001.153.255.255 IANA
001.154.000.000 001.154.255.255 美国
001.155.000.000 002.255.255.255 IANA
003.000.000.000 004.255.255.255 美国
005.000.000.000 005.147.255.255 IANA
005.148.000.000 005.148.255.255 加拿大
005.149.000.000 005.255.255.255 IANA
006.000.000.000 009.255.255.255 美国
010.000.000.000 010.255.255.255 局域网
011.000.000.000 021.233.255.255 美国
021.234.000.000 021.234.255.255 台湾省
021.235.000.000 022.255.255.255 美国
023.000.000.000 023.031.255.255 IANA
023.032.000.000 023.032.255.255 美国
023.033.000.000 023.123.255.255 IANA
023.124.000.000 023.124.255.255 美国
023.125.000.000 023.189.255.255 IANA
023.190.000.000 023.190.255.255 美国
023.191.000.000 023.255.255.255 IANA
024.000.000.000 024.035.127.255 美国
024.035.128.000 024.037.255.255 加拿大
024.038.000.000 024.038.015.255 美国
024.038.016.000 024.038.159.255 加拿大
024.038.160.000 024.038.175.255 美国
024.038.176.000 024.038.191.255 加拿大
024.038.192.000 024.038.223.255 美国
024.038.224.000 024.038.255.255 加拿大
024.039.000.000 024.039.127.255 美国
024.039.128.000 024.039.255.255 加拿大
024.040.000.000 024.040.079.255 美国
024.040.080.000 024.040.095.255 加拿大
024.040.096.000 024.040.111.255 美国
024.040.112.000 024.040.255.255 加拿大
024.041.000.000 024.041.095.255 美国
024.041.096.000 024.043.255.255 加拿大
024.044.000.000 024.056.255.255 美国
024.057.000.000 024.057.255.255 加拿大
024.058.000.000 024.063.255.255 美国
024.064.000.000 024.072.143.255 加拿大
024.072.144.000 024.075.255.255 美国
024.076.000.000 024.087.255.255 加拿大
024.088.000.000 024.089.031.255 美国
024.089.032.000 024.089.063.255 Unknown
024.089.064.000 024.089.127.255 加拿大
024.089.128.000 024.089.191.255 美国
024.089.192.000 024.089.255.255 加拿大
024.090.000.000 024.099.255.255 美国
024.100.000.000 024.103.255.255 加拿大
024.104.000.000 024.107.255.255 美国
024.108.000.000 024.109.255.255 加拿大
024.110.000.000 024.110.255.255 美国
024.111.000.000 024.112.255.255 加拿大
024.113.000.000 024.113.191.255 美国
024.113.192.000 024.114.255.255 加拿大
024.115.000.000 024.121.255.255 美国
024.122.000.000 024.122.255.255 加拿大
024.123.000.000 024.129.223.255 美国
024.129.224.000 024.129.239.255 加拿大
024.129.240.000 024.129.255.255 Unknown
024.130.000.000 024.131.255.255 美国
024.132.000.000 024.135.255.255 荷兰
024.136.000.000 024.137.031.255 美国
024.137.032.000 024.137.047.255 加拿大
024.137.048.000 024.137.063.255 Unknown
024.137.064.000 024.137.127.255 加拿大
024.137.128.000 024.137.191.255 美国
024.137.192.000 024.137.223.255 加拿大
024.137.224.000 024.137.255.255 Unknown
024.138.000.000 024.138.079.255 加拿大
024.138.080.000 024.138.095.255 Unknown
024.138.096.000 024.138.111.255 加拿大
024.138.112.000 024.138.127.255 Unknown
024.138.128.000 024.138.191.255 加拿大
024.138.192.000 024.138.255.255 波多黎各
024.139.000.000 024.139.031.255 加拿大
024.139.032.000 024.139.063.255 Unknown
024.139.064.000 024.139.095.255 波多黎各
024.139.096.000 024.139.127.255 Unknown
024.139.128.000 024.139.223.255 波多黎各
024.139.224.000 024.139.255.255 Unknown
024.140.000.000 024.140.255.255 美国
024.141.000.000 024.141.255.255 加拿大
024.142.000.000 024.143.047.255 美国
024.143.048.000 024.143.063.255 加拿大
024.143.064.000 024.143.095.255 美国
024.143.096.000 024.143.127.255 加拿大
024.143.128.000 024.143.175.255 美国
024.143.176.000 024.143.223.255 加拿大
024.143.224.000 024.145.255.255 美国
024.146.000.000 024.146.255.255 加拿大
024.147.000.000 024.149.031.255 美国
34 楼
Hooopo
2009-08-21
引用
有效代码30多行,使用了PHPWind的IP数据库(稍稍改了改格式,源码里提供了工具)
工具在哪里?
33 楼
yiminghe
2009-03-24
你这个有什么优势?
用过纯真ip库,好用,有很详细的格式说明,一次加载到内存挺方便的
用过纯真ip库,好用,有很详细的格式说明,一次加载到内存挺方便的
32 楼
sevk
2009-03-18
如果文件操作频繁,操作系统应该会自动加载文件到内存的,而且会根据内存大小,操作系统会自动卸载文件的吧?
那个ruby解纯真数据库的代码,好像有BUG,哪位大大教一下怎么改!
那个ruby解纯真数据库的代码,好像有BUG,哪位大大教一下怎么改!
31 楼
fanix
2009-03-10
这个东西真是好用,十分感谢
29 楼
greencoffee
2009-03-03
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class IPFinder {
private String DbPath = "/IPData.Dat"; //IP纯真数据库
private String Country, LocalStr;
private long IPN;
private int RecordCount, CountryFlag;
private long RangE, RangB, OffSet, StartIP, EndIP, FirstStartIP,LastStartIP, EndIPOff;
private RandomAccessFile fis;
private byte[] buff;
/**
* 用法:
* IPFinder f = new IPFinder(path);
* f.seek(ip);
* String pc = f.getCountry();得到省市
* String lc = f.getLocal();得到地区
*
* @param path
*/
public IPFinder(String path) {
this.DbPath = path + "WEB-INF/classes/com/hwxsoft/qlfw/common" + this.DbPath;
}
private long B2L(byte[] b) {
long ret = 0;
for (int i = 0; i < b.length; i++) {
long t = 1L;
for (int j = 0; j < i; j++)
t = t * 256L;
ret += ((b[i] < 0) ? 256 + b[i] : b[i]) * t;
}
return ret;
}
private long ipToInt(String ip) {
String[] arr = ip.split("\\.");
long ret = 0;
for (int i = 0; i < arr.length; i++) {
long l = 1;
for (int j = 0; j < i; j++)
l *= 256;
try {
ret += Long.parseLong(arr[arr.length - i - 1]) * l;
}
catch (Exception e) {
ret += 0;
}
}
return ret;
}
public void seek(String ip) throws Exception {
this.IPN = ipToInt(ip);
fis = new RandomAccessFile(this.DbPath, "r");
buff = new byte[4];
fis.seek(0);
fis.read(buff);
FirstStartIP = this.B2L(buff);
fis.read(buff);
LastStartIP = this.B2L(buff);
RecordCount = (int) ((LastStartIP - FirstStartIP) / 7);
if (RecordCount <= 1) {
LocalStr = Country = "未知";
throw new Exception();
}
RangB = 0;
RangE = RecordCount;
long RecNo;
do {
RecNo = (RangB + RangE) / 2;
getStartIP(RecNo);
if (IPN == StartIP) {
RangB = RecNo;
break;
}
if (IPN > StartIP)
RangB = RecNo;
else
RangE = RecNo;
}
while (RangB < RangE - 1);
getStartIP(RangB);
getEndIP();
getCountry(IPN);
fis.close();
}
private String getFlagStr(long OffSet) throws IOException {
int flag = 0;
do {
fis.seek(OffSet);
buff = new byte[1];
fis.read(buff);
flag = (buff[0] < 0) ? 256 + buff[0] : buff[0];
if (flag == 1 || flag == 2) {
buff = new byte[3];
fis.read(buff);
if (flag == 2) {
CountryFlag = 2;
EndIPOff = OffSet - 4;
}
OffSet = this.B2L(buff);
}
else
break;
}
while (true);
if (OffSet < 12) {
return "";
}
else {
fis.seek(OffSet);
return getStr();
}
}
private String getStr() throws IOException {
long l = fis.length();
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
byte c = fis.readByte();
do {
byteout.write(c);
c = fis.readByte();
}
while (c != 0 && fis.getFilePointer() < l);
return byteout.toString();
}
/**
* 得到省市
* @param ip
* @throws IOException
*/
private void getCountry(long ip) throws IOException {
if (CountryFlag == 1 || CountryFlag == 2) {
Country = getFlagStr(EndIPOff + 4);
if (CountryFlag == 1) {
LocalStr = getFlagStr(fis.getFilePointer());
if (IPN >= ipToInt("255.255.255.0") && IPN <= ipToInt("255.255.255.255")) {
LocalStr = getFlagStr(EndIPOff + 21);
Country = getFlagStr(EndIPOff + 12);
}
}
else {
LocalStr = getFlagStr(EndIPOff +;
}
}
else {
Country = getFlagStr(EndIPOff + 4);
LocalStr = getFlagStr(fis.getFilePointer());
}
}
private long getEndIP() throws IOException {
fis.seek(EndIPOff);
buff = new byte[4];
fis.read(buff);
EndIP = this.B2L(buff);
buff = new byte[1];
fis.read(buff);
CountryFlag = (buff[0] < 0) ? 256 + buff[0] : buff[0];
return EndIP;
}
private long getStartIP(long RecNo) throws IOException {
OffSet = FirstStartIP + RecNo * 7;
fis.seek(OffSet);
buff = new byte[4];
fis.read(buff);
StartIP = this.B2L(buff);
buff = new byte[3];
fis.read(buff);
EndIPOff = this.B2L(buff);
return StartIP;
}
/**
* 得到地段
* @return
*/
public String getLocal() {
return this.LocalStr;
}
public String getCountry() {
return this.Country;
}
public void setPath(String path) {
this.DbPath = path;
}
}
import java.io.IOException;
import java.io.RandomAccessFile;
public class IPFinder {
private String DbPath = "/IPData.Dat"; //IP纯真数据库
private String Country, LocalStr;
private long IPN;
private int RecordCount, CountryFlag;
private long RangE, RangB, OffSet, StartIP, EndIP, FirstStartIP,LastStartIP, EndIPOff;
private RandomAccessFile fis;
private byte[] buff;
/**
* 用法:
* IPFinder f = new IPFinder(path);
* f.seek(ip);
* String pc = f.getCountry();得到省市
* String lc = f.getLocal();得到地区
*
* @param path
*/
public IPFinder(String path) {
this.DbPath = path + "WEB-INF/classes/com/hwxsoft/qlfw/common" + this.DbPath;
}
private long B2L(byte[] b) {
long ret = 0;
for (int i = 0; i < b.length; i++) {
long t = 1L;
for (int j = 0; j < i; j++)
t = t * 256L;
ret += ((b[i] < 0) ? 256 + b[i] : b[i]) * t;
}
return ret;
}
private long ipToInt(String ip) {
String[] arr = ip.split("\\.");
long ret = 0;
for (int i = 0; i < arr.length; i++) {
long l = 1;
for (int j = 0; j < i; j++)
l *= 256;
try {
ret += Long.parseLong(arr[arr.length - i - 1]) * l;
}
catch (Exception e) {
ret += 0;
}
}
return ret;
}
public void seek(String ip) throws Exception {
this.IPN = ipToInt(ip);
fis = new RandomAccessFile(this.DbPath, "r");
buff = new byte[4];
fis.seek(0);
fis.read(buff);
FirstStartIP = this.B2L(buff);
fis.read(buff);
LastStartIP = this.B2L(buff);
RecordCount = (int) ((LastStartIP - FirstStartIP) / 7);
if (RecordCount <= 1) {
LocalStr = Country = "未知";
throw new Exception();
}
RangB = 0;
RangE = RecordCount;
long RecNo;
do {
RecNo = (RangB + RangE) / 2;
getStartIP(RecNo);
if (IPN == StartIP) {
RangB = RecNo;
break;
}
if (IPN > StartIP)
RangB = RecNo;
else
RangE = RecNo;
}
while (RangB < RangE - 1);
getStartIP(RangB);
getEndIP();
getCountry(IPN);
fis.close();
}
private String getFlagStr(long OffSet) throws IOException {
int flag = 0;
do {
fis.seek(OffSet);
buff = new byte[1];
fis.read(buff);
flag = (buff[0] < 0) ? 256 + buff[0] : buff[0];
if (flag == 1 || flag == 2) {
buff = new byte[3];
fis.read(buff);
if (flag == 2) {
CountryFlag = 2;
EndIPOff = OffSet - 4;
}
OffSet = this.B2L(buff);
}
else
break;
}
while (true);
if (OffSet < 12) {
return "";
}
else {
fis.seek(OffSet);
return getStr();
}
}
private String getStr() throws IOException {
long l = fis.length();
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
byte c = fis.readByte();
do {
byteout.write(c);
c = fis.readByte();
}
while (c != 0 && fis.getFilePointer() < l);
return byteout.toString();
}
/**
* 得到省市
* @param ip
* @throws IOException
*/
private void getCountry(long ip) throws IOException {
if (CountryFlag == 1 || CountryFlag == 2) {
Country = getFlagStr(EndIPOff + 4);
if (CountryFlag == 1) {
LocalStr = getFlagStr(fis.getFilePointer());
if (IPN >= ipToInt("255.255.255.0") && IPN <= ipToInt("255.255.255.255")) {
LocalStr = getFlagStr(EndIPOff + 21);
Country = getFlagStr(EndIPOff + 12);
}
}
else {
LocalStr = getFlagStr(EndIPOff +;
}
}
else {
Country = getFlagStr(EndIPOff + 4);
LocalStr = getFlagStr(fis.getFilePointer());
}
}
private long getEndIP() throws IOException {
fis.seek(EndIPOff);
buff = new byte[4];
fis.read(buff);
EndIP = this.B2L(buff);
buff = new byte[1];
fis.read(buff);
CountryFlag = (buff[0] < 0) ? 256 + buff[0] : buff[0];
return EndIP;
}
private long getStartIP(long RecNo) throws IOException {
OffSet = FirstStartIP + RecNo * 7;
fis.seek(OffSet);
buff = new byte[4];
fis.read(buff);
StartIP = this.B2L(buff);
buff = new byte[3];
fis.read(buff);
EndIPOff = this.B2L(buff);
return StartIP;
}
/**
* 得到地段
* @return
*/
public String getLocal() {
return this.LocalStr;
}
public String getCountry() {
return this.Country;
}
public void setPath(String path) {
this.DbPath = path;
}
}
28 楼
architectcom
2009-03-01
我以前用java写过一个利用纯真IP数据库查询IP地址。
程序在shell中输入:
java IPSearcher 166 111 40 9
输出:
166.111.40.9
166.111.40.0
166.111.40.127
清华大学
建筑学院(建筑馆)
详细情况请看:
http://archgo.com/index.php?option=com_content&view=article&id=60:ipjavaip&catid=29:software-express&Itemid=18
程序在shell中输入:
java IPSearcher 166 111 40 9
输出:
166.111.40.9
166.111.40.0
166.111.40.127
清华大学
建筑学院(建筑馆)
详细情况请看:
http://archgo.com/index.php?option=com_content&view=article&id=60:ipjavaip&catid=29:software-express&Itemid=18
27 楼
qichunren
2009-02-26
为什么IP数据库不是标准的数据库格式,如mysql.
26 楼
wosmvp
2009-02-22
当想通过shell调用,查询一个IP,就加载全部文件,就有点过了
这里是查询文件一次后缓存此文件。
这里是查询文件一次后缓存此文件。
25 楼
七猫
2009-02-20
这里的二分查文件,不停的文件seek,read,像服务器端没必要,一次读完就ok了。
24 楼
七猫
2009-02-20
如果是一次性加载到内存,就没必要搞得太麻烦了。我以前做的是C++的版本,搞了一个std::map,然后lower_bound之类的(对应一个整数的key,ip地址转成int)查找,速度是非常的快。
23 楼
wosmvp
2009-02-20
orange0513 写道
刚用netbeans打开data文件看了下,发现之前删文件开头空白的时候,完了还多出来一个.,不知道怎么搞的。现在好像没问题了。我用1000个随机ip看了下,没发现大些的UNKNOWN。用的WIN XP+RUBY1.9.1,data文件和结果在附件里,不过效率确实低了。
[size=xx-small]
[size=xx-small]
user system total real 13.969000 0.500000 14.469000 ( 14.515625) % cumulative self self total time seconds seconds calls ms/call ms/call name 20.77 2.90 2.90 33 88.03 88.03 IO#each 5.72 3.71 0.80 18071 0.04 0.06 BasicObject#!= 4.88 4.39 0.68 45503 0.01 0.01 Array#[] 4.81 5.06 0.67 2000 0.34 0.46 Array#each 3.48 5.55 0.49 13366 0.04 0.04 String#split 3.11 5.98 0.43 20071 0.02 0.02 Fixnum#== 2.88 6.38 0.40 11358 0.04 0.05 Comparable.> 2.78 6.77 0.39 6697 0.06 0.07 Comparable.< 2.45 7.12 0.34 992 0.35 0.77 IPParse#dichotomizing 2.12 7.41 0.30 18071 0.02 0.02 String#<=> 1.78 7.66 0.25 1000 0.25 0.88 IPParse#format 1.44 7.86 0.20 11366 0.02 0.02 Fixnum#/ 1.24 8.04 0.17 2000 0.09 0.12 Array#join 1.12 8.19 0.16 11366 0.01 0.01 Array#size 0.89 8.32 0.12 2001 0.06 0.09 Integer#times 0.87 8.44 0.12 5850 0.02 0.02 Fixnum#to_s 0.68 8.53 0.10 5000 0.02 0.02 String#to_i 0.66 8.63 0.09 1000 0.09 0.58 Object#randip 0.56 8.70 0.08 2000 0.04 0.38 Enumerable.inject 0.55 8.78 0.08 1000 0.08 0.08 IO#<< 0.44 8.84 0.06 4000 0.02 0.02 Array#<< 0.34 8.89 0.05 4000 0.01 0.01 String#rjust 0.34 8.94 0.05 4000 0.01 0.01 Kernel.rand 0.34 8.99 0.05 3000 0.02 0.02 String#to_s 0.23 9.02 0.03 4000 0.01 0.01 Fixnum#> 0.22 9.05 0.03 1000 0.03 0.17 Enumerator#each 0.21 9.08 0.03 1000 0.03 0.03 String#=~ 0.11 9.10 0.02 8 2.00 2.00 Comparable.>= 0.11 9.11 0.02 883 0.02 0.02 Array#[]= 0.11 9.13 0.02 1144 0.01 0.01 String#[] 0.11 9.14 0.02 883 0.02 0.02 File#exist? 0.11 9.16 0.02 1000 0.02 0.02 String#strip 0.11 9.17 0.01 2 7.50 7.50 Kernel.require 0.11 9.19 0.01 34 0.44 85.88 IO#open 0.00 9.19 0.00 8 0.00 0.00 Comparable.<= 0.00 9.19 0.00 2 0.00 0.00 Time#now 0.00 9.19 0.00 2 0.00 0.00 Time#initialize 0.00 9.19 0.00 2 0.00 0.00 Benchmark.times 0.00 9.19 0.00 2 0.00 0.00 Process.times 0.00 9.19 0.00 2 0.00 0.00 Struct#initialize 0.00 9.19 0.00 1 0.00 0.00 String#ljust 0.00 9.19 0.00 2 0.00 0.00 Class#new 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Report#initialize 0.00 9.19 0.00 3 0.00 0.00 Kernel.print 0.00 9.19 0.00 1850 0.00 0.00 File#dirname 0.00 9.19 0.00 1003 0.00 0.00 IO#write 0.00 9.19 0.00 1 0.00 0.00 Kernel.iterator? 0.00 9.19 0.00 2 0.00 0.00 IO#sync= 0.00 9.19 0.00 1 0.00 0.00 IO#sync 0.00 9.19 0.00 33 0.00 88.03 Enumerable.to_a 0.00 9.19 0.00 34 0.00 0.00 IO#close 0.00 9.19 0.00 1 0.00 0.00 String#+ 0.00 9.19 0.00 1 0.00 0.00 String#* 0.00 9.19 0.00 1 0.00 0.00 Module#private 0.00 9.19 0.00 1 0.00 0.00 Encoding#default_external= 0.00 9.19 0.00 4 0.00 0.00 IO#set_encoding 0.00 9.19 0.00 1 0.00 0.00 String#== 0.00 9.19 0.00 1 0.00 0.00 Module#protected 0.00 9.19 0.00 1 0.00 0.00 Module#module_function 0.00 9.19 0.00 9 0.00 0.00 Module#attr_reader 0.00 9.19 0.00 4 0.00 0.00 Class#inherited 0.00 9.19 0.00 32 0.00 0.00 Module#method_added 0.00 9.19 0.00 144 0.00 0.00 String#length 0.00 9.19 0.00 34 0.00 0.00 File#initialize 0.00 9.19 0.00 9 0.00 0.00 BasicObject#singleton_method_added 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#utime 0.00 9.19 0.00 5 0.00 0.00 Float#- 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#stime 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#cutime 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#cstime 0.00 9.19 0.00 2 0.00 0.00 Time#to_f 0.00 9.19 0.00 3 0.00 0.00 Float#+ 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Tms#initialize 0.00 9.19 0.00 1 0.00 0.00 Benchmark.measure 0.00 9.19 0.00 1 0.00 0.00 String#initialize_copy 0.00 9.19 0.00 1 0.00 0.00 Kernel.dup 0.00 9.19 0.00 7 0.00 0.00 String#gsub! 0.00 9.19 0.00 4 0.00 0.00 String#% 0.00 9.19 0.00 1 0.00 0.00 Kernel.format 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Tms#format 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Report#item 0.00 9.19 0.00 1 0.00 0.00 Module#=== 0.00 9.19 0.00 1 0.00 0.00 Benchmark.benchmark 0.00 9.19 0.00 1 0.00 0.00 Benchmark.bm 0.00 13.98 0.00 1 0.00 13984.00 #toplevel[/size]
嗯,我说的UNKNOW不是你说的UNKNOW的意思,是测试跑不过的意思,
格式化文件,我提供了一个里面提供了一个脚本,win下去掉第一行,跑跑应该可以的正确得到格式的
现在修改你的代码 raise 为return false测试全过了,程序应该可以跑出正确结果了
22 楼
orange0513
2009-02-20
刚用netbeans打开data文件看了下,发现之前删文件开头空白的时候,完了还多出来一个.,不知道怎么搞的。现在好像没问题了。我用1000个随机ip看了下,没发现大些的UNKNOWN。用的WIN XP+RUBY1.9.1,data文件和结果在附件里,不过效率确实低了。
[size=xx-small]
[size=xx-small]
user system total real 13.969000 0.500000 14.469000 ( 14.515625) % cumulative self self total time seconds seconds calls ms/call ms/call name 20.77 2.90 2.90 33 88.03 88.03 IO#each 5.72 3.71 0.80 18071 0.04 0.06 BasicObject#!= 4.88 4.39 0.68 45503 0.01 0.01 Array#[] 4.81 5.06 0.67 2000 0.34 0.46 Array#each 3.48 5.55 0.49 13366 0.04 0.04 String#split 3.11 5.98 0.43 20071 0.02 0.02 Fixnum#== 2.88 6.38 0.40 11358 0.04 0.05 Comparable.> 2.78 6.77 0.39 6697 0.06 0.07 Comparable.< 2.45 7.12 0.34 992 0.35 0.77 IPParse#dichotomizing 2.12 7.41 0.30 18071 0.02 0.02 String#<=> 1.78 7.66 0.25 1000 0.25 0.88 IPParse#format 1.44 7.86 0.20 11366 0.02 0.02 Fixnum#/ 1.24 8.04 0.17 2000 0.09 0.12 Array#join 1.12 8.19 0.16 11366 0.01 0.01 Array#size 0.89 8.32 0.12 2001 0.06 0.09 Integer#times 0.87 8.44 0.12 5850 0.02 0.02 Fixnum#to_s 0.68 8.53 0.10 5000 0.02 0.02 String#to_i 0.66 8.63 0.09 1000 0.09 0.58 Object#randip 0.56 8.70 0.08 2000 0.04 0.38 Enumerable.inject 0.55 8.78 0.08 1000 0.08 0.08 IO#<< 0.44 8.84 0.06 4000 0.02 0.02 Array#<< 0.34 8.89 0.05 4000 0.01 0.01 String#rjust 0.34 8.94 0.05 4000 0.01 0.01 Kernel.rand 0.34 8.99 0.05 3000 0.02 0.02 String#to_s 0.23 9.02 0.03 4000 0.01 0.01 Fixnum#> 0.22 9.05 0.03 1000 0.03 0.17 Enumerator#each 0.21 9.08 0.03 1000 0.03 0.03 String#=~ 0.11 9.10 0.02 8 2.00 2.00 Comparable.>= 0.11 9.11 0.02 883 0.02 0.02 Array#[]= 0.11 9.13 0.02 1144 0.01 0.01 String#[] 0.11 9.14 0.02 883 0.02 0.02 File#exist? 0.11 9.16 0.02 1000 0.02 0.02 String#strip 0.11 9.17 0.01 2 7.50 7.50 Kernel.require 0.11 9.19 0.01 34 0.44 85.88 IO#open 0.00 9.19 0.00 8 0.00 0.00 Comparable.<= 0.00 9.19 0.00 2 0.00 0.00 Time#now 0.00 9.19 0.00 2 0.00 0.00 Time#initialize 0.00 9.19 0.00 2 0.00 0.00 Benchmark.times 0.00 9.19 0.00 2 0.00 0.00 Process.times 0.00 9.19 0.00 2 0.00 0.00 Struct#initialize 0.00 9.19 0.00 1 0.00 0.00 String#ljust 0.00 9.19 0.00 2 0.00 0.00 Class#new 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Report#initialize 0.00 9.19 0.00 3 0.00 0.00 Kernel.print 0.00 9.19 0.00 1850 0.00 0.00 File#dirname 0.00 9.19 0.00 1003 0.00 0.00 IO#write 0.00 9.19 0.00 1 0.00 0.00 Kernel.iterator? 0.00 9.19 0.00 2 0.00 0.00 IO#sync= 0.00 9.19 0.00 1 0.00 0.00 IO#sync 0.00 9.19 0.00 33 0.00 88.03 Enumerable.to_a 0.00 9.19 0.00 34 0.00 0.00 IO#close 0.00 9.19 0.00 1 0.00 0.00 String#+ 0.00 9.19 0.00 1 0.00 0.00 String#* 0.00 9.19 0.00 1 0.00 0.00 Module#private 0.00 9.19 0.00 1 0.00 0.00 Encoding#default_external= 0.00 9.19 0.00 4 0.00 0.00 IO#set_encoding 0.00 9.19 0.00 1 0.00 0.00 String#== 0.00 9.19 0.00 1 0.00 0.00 Module#protected 0.00 9.19 0.00 1 0.00 0.00 Module#module_function 0.00 9.19 0.00 9 0.00 0.00 Module#attr_reader 0.00 9.19 0.00 4 0.00 0.00 Class#inherited 0.00 9.19 0.00 32 0.00 0.00 Module#method_added 0.00 9.19 0.00 144 0.00 0.00 String#length 0.00 9.19 0.00 34 0.00 0.00 File#initialize 0.00 9.19 0.00 9 0.00 0.00 BasicObject#singleton_method_added 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#utime 0.00 9.19 0.00 5 0.00 0.00 Float#- 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#stime 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#cutime 0.00 9.19 0.00 2 0.00 0.00 Struct::Tms#cstime 0.00 9.19 0.00 2 0.00 0.00 Time#to_f 0.00 9.19 0.00 3 0.00 0.00 Float#+ 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Tms#initialize 0.00 9.19 0.00 1 0.00 0.00 Benchmark.measure 0.00 9.19 0.00 1 0.00 0.00 String#initialize_copy 0.00 9.19 0.00 1 0.00 0.00 Kernel.dup 0.00 9.19 0.00 7 0.00 0.00 String#gsub! 0.00 9.19 0.00 4 0.00 0.00 String#% 0.00 9.19 0.00 1 0.00 0.00 Kernel.format 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Tms#format 0.00 9.19 0.00 1 0.00 0.00 Benchmark::Report#item 0.00 9.19 0.00 1 0.00 0.00 Module#=== 0.00 9.19 0.00 1 0.00 0.00 Benchmark.benchmark 0.00 9.19 0.00 1 0.00 0.00 Benchmark.bm 0.00 13.98 0.00 1 0.00 13984.00 #toplevel[/size]
21 楼
orange0513
2009-02-20
wosmvp 写道
确定找不到?
require 'rubygems'
require 'ipparse'
puts IPParse.parse('222.222.222.222') #=> 河北省石家庄市
另外代码你没有测试吧,试了几个全UNKNOW
self.dichotomizing(arg,ip) 方法中的split影响性能,所以换了
性能测试有点问题,这样测试内容将包含randip这个方法的速度了
谢谢,文件竟然没有关闭……
require 'rubygems'
require 'ipparse'
puts IPParse.parse('222.222.222.222') #=> 河北省石家庄市
另外代码你没有测试吧,试了几个全UNKNOW
self.dichotomizing(arg,ip) 方法中的split影响性能,所以换了
性能测试有点问题,这样测试内容将包含randip这个方法的速度了
谢谢,文件竟然没有关闭……
我从你发帖时写的那个地址下的data文件,不知道你后来改了没。0.txt里本身就有很多Unknown,不过大小写不一样。而且每个文件开头都有一段空白,split会出问题,我删掉了。我也没测试,刚把randip分析的结果输出到文件里看了下,是有几个没找到。好像每个文件第一条记录都没有分析出来,我再看看。那个benchmark我就随便写着看看时间,无所谓那么精确了。profile了下,主要都是IO#each消耗的时间。如果没有那个data缓存,估计会慢很多。
20 楼
wosmvp
2009-02-19
QuakeWang 写道
看了一下代码,简单易懂,和纯真的ip数据库查找算法比起来,都是采用2分法查找ip范围,不同的是你这个用空间换时间,地址信息是重复记录的,速度自然要快很多。
在github上给你pull request,一个简单的性能改进:
另外你可以试试看将这里的代码分开2次写,2个元素的数组用each感觉没有必要,而且block也会有少许的性能损失。
在github上给你pull request,一个简单的性能改进:
def self.format(ip) ip.to_s.scan(/\d+/).map{|x| x.rjust(3, '0')}.join('.') end
另外你可以试试看将这里的代码分开2次写,2个元素的数组用each感觉没有必要,而且block也会有少许的性能损失。
[ip[0,3].to_i,0].each do |f| #.... end
谢谢,已合并,性能又提升了0.*秒
分开写没有感觉到性能的提升,并且代码量也会多一些
另外你提供使用Benchmark做性能测试结果会存在偏差,因为里面包含ips.each的时间,10万次差不多也要花 0.0* 秒
19 楼
QuakeWang
2009-02-19
看了一下代码,简单易懂,和纯真的ip数据库查找算法比起来,都是采用2分法查找ip范围,不同的是你这个用空间换时间,地址信息是重复记录的,速度自然要快很多。
在github上给你pull request,一个简单的性能改进:
另外你可以试试看将这里的代码分开2次写,2个元素的数组用each感觉没有必要,而且block也会有少许的性能损失。
在github上给你pull request,一个简单的性能改进:
def self.format(ip) ip.to_s.scan(/\d+/).map{|x| x.rjust(3, '0')}.join('.') end
另外你可以试试看将这里的代码分开2次写,2个元素的数组用each感觉没有必要,而且block也会有少许的性能损失。
[ip[0,3].to_i,0].each do |f| #.... end
18 楼
wosmvp
2009-02-19
确定找不到?
require 'rubygems'
require 'ipparse'
puts IPParse.parse('222.222.222.222') #=> 河北省石家庄市
另外代码你没有测试吧,试了几个全UNKNOW
self.dichotomizing(arg,ip) 方法中的split影响性能,所以换了
性能测试有点问题,这样测试内容将包含randip这个方法的速度了
谢谢,文件竟然没有关闭……
require 'rubygems'
require 'ipparse'
puts IPParse.parse('222.222.222.222') #=> 河北省石家庄市
另外代码你没有测试吧,试了几个全UNKNOW
self.dichotomizing(arg,ip) 方法中的split影响性能,所以换了
性能测试有点问题,这样测试内容将包含randip这个方法的速度了
谢谢,文件竟然没有关闭……
相关推荐
1. **IP地址输入**:用户可以直接输入IP地址进行查询。 2. **自动识别**:工具可能具备自动识别输入是否为IP地址的功能,避免用户输入错误。 3. **地理定位**:利用纯真IP数据库,将IP地址转换为具体的地理位置信息...
总结来说,Java中根据IP获取国家和地区名称涉及的技术点包括:使用`InetAddress`处理IP地址、理解IP地址库的结构和查询机制、以及选择和使用合适的第三方库或服务进行IP定位。在实际应用中,应确保IP库的及时更新,...
3. **查询IP地址**:在解析库的帮助下,我们可以输入一个IP地址,通过二分查找等高效算法,快速定位到该IP地址在数据库中的记录。记录通常包括起始IP、结束IP以及对应地理位置的信息。 4. **提取地理位置信息**:...
试题中涉及的知识点主要集中在IP地址的解析、子网掩码的运用以及网络地址、主机地址、广播地址的计算。 1. IP地址结构:IP地址由32位二进制组成,通常分为四部分,每部分用点分十进制表示,如154.27.0.0。IP地址...
2. **IP库查询**:使用预构建的IP地址数据库,如MaxMind的GeoLite,进行查询。这些数据库会定期更新以保持准确。 3. **API服务**:如Google Maps Geocoding API或OpenStreetMap Nominatim等,可以提供IP地址的地理...
本次设计的目标是捕获网络中...2)在标准输出和日志文件写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容。
在标准输出和日志文件中写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容,当程序接收到键盘输入Ctrl+C时...
设计一个解析IP数据包的程序,并根据这个程序,说明IP数据包的结构及IP协议的相关问题,从而对IP层的工作原理有更好的理解和认识。 本实验的目标是捕获网络中的IP数据包,解析数据包的内容,见个结果显示在标准输出...
2)在标准输出和日志文件中写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容。 3)能够解析不同协议...
通过这个数据库,我们可以快速查询到一个IP地址所属的地理位置。首先,你需要从互联网上下载最新版本的纯真IP数据库,通常以SQL或文本格式提供。 在Java中,我们可以创建一个类来处理IP解析。以下是一个简单的...
在`ipparse`函数中,代码首先通过`*(IP_HEADER*)buffer`将缓冲区中的数据转化为`IP_HEADER`结构体,然后依次调用上述函数来解析并打印出每个字段的值。这一步骤是实现IP数据包解析的核心。 ### 结论 通过上述分析...
9. 源IP地址(Source IP Address)和目的IP地址(Destination IP Address):各32位,标识发送方和接收方的网络地址。 10. 可选字段(Options):根据首部长度字段,可能存在的可选字段,用于扩展功能。 在C语言中...
这通常涉及到DNS反向查询,将IP地址映射回其对应的组织或运营商。这对于网站统计、网络安全分析、地理位置服务等应用非常有用。例如,你可以使用这个库来识别访问你网站的用户可能来自哪个网络服务提供商,或者在...
头部包含了控制信息,如版本号、头部长度、服务类型(TOS)、总长度、标识符、标志、片段偏移、生存时间(TTL)、协议类型、头部校验和以及源和目的IP地址。数据部分则携带上层协议(如TCP、UDP或ICMP)的数据。 2...
- 输出并记录IP包头的关键信息,包括版本、头长度、服务类型(TOS)、总长度、标识符、标志、片段偏移、生存时间(TTL)、上层协议类型、头校验和、源IP地址和目标IP地址等。 - 提供一个优雅的退出机制,例如在接收...
1. **了解IP数据包的基本结构**:包括版本号、头部长度、服务类型、总长度、标识、标志、片段偏移、生存时间(TTL)、协议类型、头部校验和、源IP地址、目的IP地址等。 2. **理解IP协议的工作原理**:包括IP数据包在...
- **源IP地址和目的IP地址**: 各32位,分别表示发送方和接收方的IP地址。 - **选项字段和填充字段**: 可选字段,用于携带额外的信息或对齐。 2. **IP协议**: - **功能**: IP协议负责在网络层将数据从源节点传递...
2)在标准输出和日志文件中写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容。 3)当程序接收到键盘输入...