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 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 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  LV6 2022年3月15日
农村拓哉 2021年12月7日
暂无贡献等级
13561143836  LV7 2021年11月10日
明天更美好  LV10 2021年9月9日
铁血战士  LV1 2021年6月2日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友