Skip to content

Instantly share code, notes, and snippets.

Created February 18, 2009 07:44
Show Gist options
  • Save anonymous/66248 to your computer and use it in GitHub Desktop.
Save anonymous/66248 to your computer and use it in GitHub Desktop.
#从纯真IP数据库里查询
def search_ip_cz(ip)
#IP数据文件路径
#ip='202.38.64.10'
dat_path = "QQWry.Dat"
#检查IP地址
# if not ip~=/^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/
# return 'IP Address Error'
# end
fd = File.open(dat_path, "rb")
ips = ip.split('.')
ip_num = ips[0].to_i * 16777216 + ips[1].to_i * 65536 + ips[2].to_i * 256 + ips[3].to_i
data_begin = fd.read(4)
data_end = fd.read(4)
ipbegin= data_begin.unpack('L').join('').to_i
if ipbegin < 0
ipbegin += 2**32
end
ipend= data_end.unpack('L').join('').to_i
if ipend < 0
ipend += 2**32
end
ip_allnum = (ipend - ipbegin) / 7 + 1
begin_num = 0
end_num = ip_allnum
ip1_num=0
ip2_num=0
ip_addr1=""
ip_addr2=""
#使用二分查找法从索引记录中搜索匹配的IP记录
while ip1_num>ip_num or ip2_num<ip_num
middle= ((end_num + begin_num) / 2).to_i
#偏移指针到索引位置读取4个字节
fd.seek(ipbegin + 7 * middle)
ip_data1 = fd.read(4)
if ip_data1.length < 4
fd.close
return 'System Error'
end
#提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂
ip1_num = ip_data1.unpack('L').join('').to_i
if ip1_num < 0
ip1_num += 2**32
end
#提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
if ip1_num > ip_num
end_num = middle
redo
end
#取完上一个索引后取下一个索引
data_seek = fd.read(3)
if data_seek.length < 3
fd.close
return 'System Error';
end
data_seek = (data_seek+0.chr).unpack('L').join('').to_i #data_seek = implode('', unpack('L', $data_seek.chr(0)));
fd.seek(data_seek)
ip_data2 = fd.read(4)
if ip_data2.length<4
fd.close
return 'System Error'
end
ip2_num = ip_data2.unpack('L').join('').to_i
if ip2_num < 0
ip2_num += 2**32
end
#没找到提示未知
if ip2_num < ip_num
end
if middle == begin_num
fd.close
return 'Unknown'
end
begin_num = middle
end
ip_flag = fd.read(1)
if ip_flag == 1.chr
ip_seek = fd.read(3)
if ip_seek.length < 3
fd.close
return 'System Error'
end
ip_seek = (ip_seek+0.chr).unpack('L').join('').to_i #implode('', unpack('L', $ip_seek.chr(0)));
fd.seek(ip_seek)
ip_flag = fd.read(1)
end
if ip_flag == 2.chr
addr_seek = fd.read(3)
if addr_seek.length < 3
fd.close
return 'System Error'
end
ip_flag = fd.read(1)
if ip_flag == 2.chr
addr_seek2 = fd.read(3)
if addr_seek2.length< 3
fd.close
return 'System Error'
end
addr_seek2 =(addr_seek2+0.chr).unpack('L').join('').to_i# implode('', unpack('L', $addr_seek2.chr(0)));
fd.seek(addr_seek2)
else
fd.seek(-1, IO::SEEK_CUR)
end
while (char = fd.read(1)) != 0.chr
ip_addr2 += char# ip_addr2 .= char
end
addr_seek =(addr_seek+0.chr).unpack('L').join('').to_i#$addr_seek = implode('', unpack('L', $addr_seek.chr(0)));
fd.seek(addr_seek)
while (char = fd.read(1)) != 0.chr
ip_addr1 += char#$ip_addr1 .= $char;
end
else
fd.seek(-1, IO::SEEK_CUR)
while ( char = fd.read(1)) != 0.chr
ip_addr1 += char#ip_addr1 .= char;
end
ip_flag = fd.read(1)
if ip_flag == 2.chr
addr_seek2 = fd.read(3)
if addr_seek2.length < 3
fd.close
return 'System Error'
end
addr_seek2 = (addr_seek2+0.chr).unpack('L').join('').to_i#implode('', unpack('L', $addr_seek2.chr(0)));
fd.seek(addr_seek2)
else
fd.seek(-1, IO::SEEK_CUR)
end
while (char = fd.read(1)) != 0.chr
ip_addr2 += char# ip_addr2 .= char
end
end
# fd.close
#最后做相应的替换操作后返回结果
#if(preg_match('/http/i', $ip_addr2)) {
# $ip_addr2 = '';
#}
if (ip_addr2=~/http(\s|\S)/)!=nil
ip_addr2 = ''
end
ip_addr = "#{ip_addr1} #{ip_addr2}"
ip_addr.gsub!(/(\S|\s)*CZ88.(NET|Net)(\S|\s)*/,'')#$ip_addr = preg_replace('/CZ88.Net/is', '', $ip_addr);
#$ip_addr = preg_replace('/^s*/is', '', $ip_addr);
#$ip_addr = preg_replace('/s*$/is', '', $ip_addr);
if (ip_addr=~/http(\s|\S)/)!=nil or ip_addr==""
ip_addr = 'Unknown'
end
# print ip_addr
return ip_addr
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment