java 取物理地址吗_java通过IP地址获取物理位置

1 import java.io.*;2 import java.util.*;3 importjava.util.regex.Matcher;4 importjava.util.regex.Pattern;5 importjava.net.InetAddress;6 importjava.net.UnknownHostException;7 importjava.nio.ByteOrder;8 importjava.nio.MappedByteBuffer;9 importjava.nio.channels.FileChannel;10

11 /**

12 * 纯真ip查询主程序13 * QQWry.Dat保存在当前目录14 *@author_hhh_15 *@version0.1, 04/23/0816 */

17 public classIpAddress {18

19 //数据库地址

20 private String dataPath = "QQWry.dat";21 //随机文件访问类

22 private RandomAccessFile ipFile = null;23 //单一模式实例

24 private static IpAddress instance = newIpAddress();25 //ip开始结束位置

26 private long ipBegin=0L;27 private long ipEnd=0L;28 //ip总数

29 private long ipSum=0L;30 //国家,地区

31 private String country="";32 private String area="";33

34 //一些固定常量,比如记录长度等等

35 private static final int RECORD_LENGTH = 7;36 private static final byte AREA_FOLLOWED = 0x01;37 private static final byte NO_AREA = 0x02;38

39 /*

40 * 私有构造函数41 */

42 privateIpAddress() {43 try{44 ipFile = new RandomAccessFile(new File(dataPath).getAbsolutePath(), "r");45 } catch(FileNotFoundException e) {46 System.out.println("IP地址信息文件没有找到,IP显示功能将无法使用");47 e.printStackTrace();48 }49 if(ipFile != null) {50 try{51 ipBegin = byteArrayToLong(readBytes(0,4));52 ipEnd = byteArrayToLong(readBytes(4,4));53 if(ipBegin == -1 || ipEnd == -1) {54 ipFile.close();55 ipFile = null;56 }57 } catch(IOException e) {58 System.out.println("IP地址信息文件格式有错误,IP显示功能将无法使用");59 e.printStackTrace();60 }61 }62 ipSum = (ipEnd-ipBegin)/RECORD_LENGTH+1;63 }64

65 /**

66 * 在指定位置读取一定数目的字节67 *@paramoffset 位置68 *@paramnum 多少个字节69 *@returnret70 */

71 private byte[] readBytes(long offset, intnum) {72 byte[] ret = new byte[num];73 try{74 ipFile.seek(offset);75

76 for(int i=0; i != num; i++) {77 ret[i] =ipFile.readByte();78 }79 returnret;80 } catch(IOException e) {81 e.printStackTrace();82 System.out.println("读取文件失败_readBytes");83 returnret;84 }85 }86

87 /**

88 * 当前位置读取一定数目的字节89 *@paramnum 多少个字节90 *@returnret91 */

92 private byte[] readBytes(intnum) {93 byte[] ret = new byte[num];94 try{95 for(int i=0; i != num; i++) {96 ret[i] =ipFile.readByte();97 }98 returnret;99 } catch(IOException e) {100 System.out.println("读取文件失败_readBytes");101 returnret;102 }103 }104

105 /**

106 * 对little-endian字节序进行了转换107 * byte[]转换为long108 *@paramb109 *@returnret110 */

111 private long byteArrayToLong(byte[] b) {112 long ret = 0;113 for(int i=0; i

119 /**

120 * 对little-endian字节序进行了转换121 *@paramip ip的字节数组形式122 *@returnip的字符串形式123 */

124 private String byteArrayToStringIp(byte[] ip) {125 StringBuffer sb = newStringBuffer();126 for(int i=ip.length-1; i>=0; i--) {127 sb.append(ip[i] & 0xFF);128 sb.append(".");129 }130 sb.deleteCharAt(sb.length()-1);131 returnsb.toString();132 }133

134 /**

135 * 把ip字符串转换为long型136 *@paramip137 *@returnlong138 */

139 private longStingIpToLong(String ip) {140 String[] arr = ip.split("\\.");141 return (Long.valueOf(arr[0])*0x1000000 +

142 Long.valueOf(arr[1])*0x10000 +

143 Long.valueOf(arr[2])*0x100 +

144 Long.valueOf(arr[3]));145 }146

147 /**

148 * 搜索ip,二分法149 *@paramString ip字符串0.0.0.0到255.255.255.255150 *@returnlong ip所在位置151 */

152 public longseekIp(String ip) {153 long tmp =StingIpToLong(ip);154 long i=0;155 long j=ipSum;156 long m = 0;157 long lm=0L;158 while(i byteArrayToLong(readBytes(lm, 4))){166 i =m;167 }else/*if( tmp < byteArrayToLong(readBytes(lm, 4)))*/{168 j =m;169 }170 }171 System.out.println("没有找到ip");172 return -1L;173 }174 private String readArea(long offset) throwsIOException {175 ipFile.seek(offset);176 byte b =ipFile.readByte();177 if(b == 0x01 || b == 0x02) {178 long areaOffset =byteArrayToLong(readBytes(offset+1,3));179 //if(areaOffset == 0)180 //return "未知";181 //else

182 returnreadString(areaOffset);183 } else

184 returnreadString(offset);185 }186 /**

187 * 通过ip位置获取国家地区,188 * 参照纯真ip数据库结构189 *@paramoffset190 *@return国家+地区191 */

192 private String seekCountryArea(longoffset) {193 try{194 ipFile.seek(offset + 4);195 byte b =ipFile.readByte();196 if(b ==AREA_FOLLOWED)197 {198 long countryOffset = byteArrayToLong(readBytes(3));199 ipFile.seek(countryOffset);200 b =ipFile.readByte();201 if(b ==NO_AREA) {202 country = readString(byteArrayToLong(readBytes(3)));203 ipFile.seek(countryOffset + 4);204 } else

205 country =readString(countryOffset);206 //area = readArea(ipFile.getFilePointer());

207 } else if(b ==NO_AREA) {208 country = readString(byteArrayToLong(readBytes(3)));209 //area = readArea(offset + 8);

210 } else{211 country = readString(ipFile.getFilePointer() - 1);212 //area = readArea(ipFile.getFilePointer());

213 }214 return readText(country,"省(.+?)市");//+" "+area;

215 } catch(IOException e) {216 return null;217 }218 }219

220 /**

221 * 正则表达式解析数据222 *@paramresult223 * @identifier224 *@return

225 */

226 public staticString readText(String result, String identifier) {227 Pattern shopNumberPattern =Pattern.compile(identifier);228 Matcher shopNamMatcher =shopNumberPattern.matcher(result);229 if(shopNamMatcher.find())230 return shopNamMatcher.group(1);231 return "";232 }233

234 /**

235 * 从offset偏移处读取一个以0结束的字符串236 *@paramoffset237 *@returnret 读取的字符串,出错返回空字符串238 */

239 private String readString(longoffset){240 try{241 ipFile.seek(offset);242 byte[] b = new byte[128];243 inti;244 for(i=0; (b.length != i) && ((b[i]=ipFile.readByte()) != 0); i++);245 String ret = new String(b, 0 , i/*, "GBK"*/);246 ret =ret.trim();247 return (ret.equals("") ||

248 ret.indexOf("CZ88.NET") != -1 )?"未知":ret;249 } catch(IOException e) {250 System.out.println("读取文件失败_readString");251 }252 return "";253 }254

255 /**

256 * 包含字符串的ip记录257 *@paramaddr 地址258 *@returnIpRecord ip记录259 */

260

261 public ArrayListstringToIp(String addr) {262 ArrayList ret = new ArrayList();263 try{264 FileChannel fc =ipFile.getChannel();265 MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length());266 mbb.order(ByteOrder.LITTLE_ENDIAN);267 //上面3代码未使用,内存映射文件功能未写

268

269 for(long i = ipBegin+4; i != ipEnd+4; i +=RECORD_LENGTH) {270 String sca = seekCountryArea(byteArrayToLong(readBytes(i, 3)));271 if(sca.indexOf(addr) != -1) {272 IpRecord rec = newIpRecord();273 rec.address =sca;274 rec.beginIp= byteArrayToStringIp(readBytes(i-4,4));275 rec.endIp= byteArrayToStringIp(readBytes(i+3,4));276 ret.add(rec);277 }278 }279 } catch(IOException e) {280 System.out.println(e.getMessage());281 }282 returnret;283 }284

285 /**

286 * 封装ip记录,包括开始ip,结束ip和地址287 */

288 private classIpRecord {289 publicString beginIp;290 publicString endIp;291 publicString address;292

293 publicIpRecord() {294 beginIp = endIp = address = "";295 }296

297 publicString toString() {298 return beginIp + " - " + endIp + " " +address;299 }300 }301

302 /**

303 *@return单一实例304 */

305 public staticIpAddress getInstance() {306 returninstance;307 }308

309 /**

310 *@paramip311 *@returnret312 */

313 publicString IpStringToAddress(String ip) {314 //这里要添加ip格式判断315 //public boolean isIP(Strin ip)

316 long ipOffset =seekIp(ip);317 String ret =seekCountryArea(ipOffset);318 returnret;319 }320

321 /**

322 *@returnIpSum323 */

324 public longgetIpSum() {325 returnipSum;326 }327

328 public static void main(String[] args) throwsUnknownHostException {329 IpAddress ipAddr =IpAddress.getInstance();330 //ip总数

331 long l =ipAddr.getIpSum();332 System.out.println(l);333 //纯真ip数据更新时间

334 String str = ipAddr.IpStringToAddress("255.255.255.0");335 System.out.println(str);336

337 //测试

338 str = ipAddr.IpStringToAddress("222.88.59.214");339 System.out.println(str);340 str = ipAddr.IpStringToAddress("222.248.70.78");341 System.out.println(str);342 str = ipAddr.IpStringToAddress("188.1.255.255");343 System.out.println(str);344 str = ipAddr.IpStringToAddress("220.168.59.166");345 System.out.println(str);346 str = ipAddr.IpStringToAddress("221.10.61.90");347 System.out.println(str);348 InetAddress inet =InetAddress.getLocalHost();349 System.out.println("本机的ip=" +inet.getHostAddress());350 /*java.net.InetAddress addr = null;351 try{352 addr = java.net.InetAddress.getLocalHost();353 }catch(java.net.UnknownHostException e){354 e.printStackTrace();355 }356 String ip=addr.getHostAddress().toString();//获得本机IP357 System.out.print(ip);358 String address=addr.getHostName().toString();//获得本机名称359 System.out.print(address);360 str = ipAddr.IpStringToAddress(ip);361 System.out.println(str);*/

362

363

364 ArrayList al = ipAddr.stringToIp("网吧");365 Iterator it =al.iterator();366

367 File f = new File("ipdata.txt");368 try{369 if(!f.exists()) {370 f.createNewFile();371 }372 BufferedWriter out = newBufferedWriter(373 newOutputStreamWriter(374 new FileOutputStream(f, true)375 )376 );377 int i=0;378 while(it.hasNext()) {379 out.write(it.next().toString());380 out.newLine();381 i++;382 }383 out.write(newDate().toString());384 out.write("总共搜索到 "+i);385 out.close();386 }catch(IOException e){387 e.printStackTrace();388 }389

390 }391 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值