import java.io.*; import java.util.*; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class IpAddress { //数据库地址 private String dataPath = "CoralWry.dat"; //随机文件访问类 private RandomAccessFile ipFile = null; //单一模式实例 private static IpAddress instance = new IpAddress(); //ip开始结束位置 private long ipBegin=0L; private long ipEnd=0L; //ip总数 private long ipSum=0L; //国家,地区 private String country=""; private String area=""; // 一些固定常量,比如记录长度等等 private static final int RECORD_LENGTH = 7; private static final byte AREA_FOLLOWED = 0x01; private static final byte NO_AREA = 0x02; /* * 私有构造函数 */ private IpAddress() { try { ipFile = new RandomAccessFile(new File(dataPath).getAbsolutePath(), "r"); } catch (FileNotFoundException e) { System.out.println("IP地址信息文件没有找到,IP显示功能将无法使用"); } if(ipFile != null) { try { ipBegin = byteArrayToLong(readBytes(0,4)); ipEnd = byteArrayToLong(readBytes(4,4)); if(ipBegin == -1 || ipEnd == -1) { ipFile.close(); ipFile = null; } } catch (IOException e) { System.out.println("IP地址信息文件格式有错误,IP显示功能将无法使用"); } } ipSum = (ipEnd-ipBegin)/RECORD_LENGTH+1; } /** * 在指定位置读取一定数目的字节 * @param offset 位置 * @param num 多少个字节 * @return ret */ private byte[] readBytes(long offset, int num) { byte[] ret = new byte[num]; try { ipFile.seek(offset); for(int i=0; i != num; i++) { ret[i] = ipFile.readByte(); } return ret; } catch (IOException e) { System.out.println("读取文件失败_readBytes"); return ret; } } /** * 当前位置读取一定数目的字节 * @param num 多少个字节 * @return ret */ private byte[] readBytes(int num) { byte[] ret = new byte[num]; try { for(int i=0; i != num; i++) { ret[i] = ipFile.readByte(); } return ret; } catch (IOException e) { System.out.println("读取文件失败_readBytes"); return ret; } } /** * 对little-endian字节序进行了转换 * byte[]转换为long * @param b * @return ret */ private long byteArrayToLong(byte[] b) { long ret = 0; for(int i=0; i<b.length; i++) { ret |= ( b[i] << (0x8*i) & (0xFF * (long)(Math.pow(0x100,i))) ); } return ret; } /** * 对little-endian字节序进行了转换 * @param ip ip的字节数组形式 * @return ip的字符串形式 */ private String byteArrayToStringIp(byte[] ip) { StringBuffer sb = new StringBuffer(); for(int i=ip.length-1; i>=0; i--) { sb.append(ip[i] & 0xFF); sb.append("."); } sb.deleteCharAt(sb.length()-1); return sb.toString(); } /** * 把ip字符串转换为long型 * @param ip * @return long */ private long StingIpToLong(String ip) { String[] arr = ip.split("\\."); return (Long.valueOf(arr[0])*0x1000000 + Long.valueOf(arr[1])*0x10000 + Long.valueOf(arr[2])*0x100 + Long.valueOf(arr[3])); } /** * 搜索ip,二分法 * @param String ip字符串0.0.0.0到255.255.255.255 * @return long ip所在位置 */ public long seekIp(String ip) { long tmp = StingIpToLong(ip); long i=0; long j=ipSum; long m = 0; long lm=0L; while(i<j) { m = (i+j)/2; lm = m*RECORD_LENGTH + ipBegin; if( tmp == byteArrayToLong(readBytes(lm, 4))){ return byteArrayToLong(readBytes(3)); }else if(j==(i+1)) { return byteArrayToLong(readBytes(3)); }else if( tmp > byteArrayToLong(readBytes(lm, 4))){ i = m; }else/* if( tmp < byteArrayToLong(readBytes(lm, 4)))*/{ j = m; } } System.out.println("没有找到ip"); return -1L; } private String readArea(long offset) throws IOException { ipFile.seek(offset); byte b = ipFile.readByte(); if(b == 0x01 || b == 0x02) { long areaOffset =byteArrayToLong(readBytes(offset+1,3)); // if(areaOffset == 0) // return "未知"; // else return readString(areaOffset); } else return readString(offset); } /** * 通过ip位置获取国家地区, * 参照纯真ip数据库结构 * @param offset * @return 国家+地区 */ private String seekCountryArea(long offset) { try { ipFile.seek(offset + 4); byte b = ipFile.readByte(); if(b == AREA_FOLLOWED) { long countryOffset = byteArrayToLong(readBytes(3)); ipFile.seek(countryOffset); b = ipFile.readByte(); if(b == NO_AREA) { country = readString(byteArrayToLong(readBytes(3))); ipFile.seek(countryOffset + 4); } else country = readString(countryOffset); area = readArea(ipFile.getFilePointer()); } else if(b == NO_AREA) { country = readString(byteArrayToLong(readBytes(3))); area = readArea(offset + 8); } else { country = readString(ipFile.getFilePointer() - 1); area = readArea(ipFile.getFilePointer()); } return country+" "+area; } catch (IOException e) { return null; } } /** * 从offset偏移处读取一个以0结束的字符串 * @param offset * @return ret 读取的字符串,出错返回空字符串 */ private String readString(long offset){ try { ipFile.seek(offset); byte[] b = new byte[128]; int i; for(i=0; (b.length != i) && ((b[i]=ipFile.readByte()) != 0); i++); String ret = new String(b, 0 , i/*, "GBK"*/); ret = ret.trim(); return (ret.equals("") || ret.indexOf("CZ88.NET") != -1 )?"未知":ret; } catch (IOException e) { System.out.println("读取文件失败_readString"); } return ""; } /** * 包含字符串的ip记录 * @param addr 地址 * @return IpRecord ip记录 */ public ArrayList<IpRecord> stringToIp(String addr) { ArrayList<IpRecord> ret = new ArrayList<IpRecord>(); try{ FileChannel fc = ipFile.getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length()); mbb.order(ByteOrder.LITTLE_ENDIAN); //上面3代码未使用,内存映射文件功能未写 for(long i = ipBegin+4; i != ipEnd+4; i += RECORD_LENGTH) { String sca = seekCountryArea(byteArrayToLong(readBytes(i, 3))); if(sca.indexOf(addr) != -1) { IpRecord rec = new IpRecord(); rec.address = sca; rec.beginIp= byteArrayToStringIp(readBytes(i-4,4)); rec.endIp= byteArrayToStringIp(readBytes(i+3,4)); ret.add(rec); } } } catch (IOException e) { System.out.println(e.getMessage()); } return ret; } /** * 封装ip记录,包括开始ip,结束ip和地址 */ private class IpRecord { public String beginIp; public String endIp; public String address; public IpRecord() { beginIp = endIp = address = ""; } public String toString() { return beginIp + " - " + endIp + " " + address; } } /** * @return 单一实例 */ public static IpAddress getInstance() { return instance; } /** * @param ip * @return ret */ public String IpStringToAddress(String ip) { //这里要添加ip格式判断 //public boolean isIP(Strin ip) long ipOffset = seekIp(ip); String ret = seekCountryArea(ipOffset); return ret; } /** * @return IpSum */ public long getIpSum() { return ipSum; } public static void main(String[] args) { IpAddress ipAddr = IpAddress.getInstance(); //ip总数 long l = ipAddr.getIpSum(); System.out.println(l); //纯真ip数据更新时间 String str = ipAddr.IpStringToAddress("255.255.255.0"); System.out.println(str); //测试 String strValue = ipAddr.IpStringToAddress("211.96.28.105"); System.out.println(str); String [] str1=strValue.split(" "); String area=str1[0]; String come=str1[1]; int cometype=4; if(come.contains("移动")) { cometype=1; } else if(come.contains("联通")) { cometype=2; } else if(come.contains("电信")) { cometype=3; } else { cometype=4; } System.out.println(come+" "+cometype+" "+area); str = ipAddr.IpStringToAddress("211.136.115.39"); System.out.println(str); str = ipAddr.IpStringToAddress("188.1.255.255"); System.out.println(str); str = ipAddr.IpStringToAddress("220.168.59.166"); System.out.println(str); str = ipAddr.IpStringToAddress("188.67.234.23"); System.out.println(str); /* java.net.InetAddress addr = null; try{ addr = java.net.InetAddress.getLocalHost(); }catch(java.net.UnknownHostException e){ e.printStackTrace(); } String ip=addr.getHostAddress().toString();//获得本机IP System.out.print(ip); String address=addr.getHostName().toString();//获得本机名称 System.out.print(address); str = ipAddr.IpStringToAddress(ip); System.out.println(str);*/ ArrayList<IpRecord> al = ipAddr.stringToIp("网吧"); Iterator it = al.iterator(); File f = new File("ipdata.txt"); try{ if(!f.exists()) { f.createNewFile(); } BufferedWriter out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(f, true) ) ); int i=0; while(it.hasNext()) { out.write(it.next().toString()); out.newLine(); i++; } out.write(new Date().toString()); out.write("总共搜索到 "+i); out.close(); }catch(IOException e){ e.printStackTrace(); } } }

1358849392 LV21
2024年4月12日
微信网友_6166561027215360 LV2
2022年10月8日
仰望星空five LV1
2020年3月13日
skipple3 LV39
2020年3月3日
yang9999 LV1
2019年12月20日
lgp1991 LV1
2019年5月7日
快乐的男孩子 LV5
2019年1月23日
caohanren LV11
2019年1月17日
Silence丶二哈 LV13
2019年1月16日
tian2019 LV1
2019年1月10日

1358849392 LV21
2024年4月12日
ming_123_9715 LV23
2022年12月15日
wanglun_wl LV10
2022年10月18日
微信网友_6166561027215360 LV2
2022年10月8日
funcrit LV2
2022年7月18日
zhy1989wz LV7
2022年3月15日
农村拓哉
2021年12月7日
暂无贡献等级
13561143836 LV7
2021年11月10日
明天更美好 LV10
2021年9月9日
铁血战士 LV1
2021年6月2日