1. 程式人生 > >使用二分查詢法,查詢ip所在的範圍對應的code(語言為java\scala\python) java語言來實現

使用二分查詢法,查詢ip所在的範圍對應的code(語言為java\scala\python) java語言來實現

  1. 使用二分法實現查詢ip所在的範圍,並返回對應的id

start_ip end_ip code

0.0.0.0 1.0.0.255 1000000000

1.0.1.0 1.0.3.255 1156350100

1.0.4.0 1.0.7.255 1036000000

1.0.8.0 1.0.15.255 1156440100

java程式實現

行資料實體類

package IpRange;

public class MyIp {

    private long startIP;
    private long endIP;
    private String code;

    //構造方法
    public MyIp(long startIP, long endIP, String code) {
        this.startIP = startIP;
        this.endIP = endIP;
        this.code = code;
    }
    //空構造方法
    public MyIp(){}
    //toString方法

    @Override
    public String toString() {
        return "MyIp{" +
                "startIP=" + startIP +
                ", endIP=" + endIP +
                ", code='" + code + '\'' +
                '}';
    }
    //get與set方法

    public long getStartIP() {
        return startIP;
    }

    public void setStartIP(long startIP) {
        this.startIP = startIP;
    }

    public long getEndIP() {
        return endIP;
    }

    public void setEndIP(long endIP) {
        this.endIP = endIP;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

ip地址轉換工具類

package IpRange;

public class IPUtils {
    /**
     * ip地址轉成long型數字
     * 將IP地址轉化成整數的方法如下:
     * 1、通過String的split方法按.分隔得到4個長度的陣列
     * 2、通過左移位操作(<<)給每一段的數字加權,第一段的權為2的24次方,第二段的權為2的16次方,第三段的權為2的8次方,最後一段的權為1
     * @param strIp
     * @return
     */
    public static long ipToLong(String strIp) {
        String[]ip = strIp.split("\\.");
        return (Long.parseLong(ip[0]) << 24) +
                (Long.parseLong(ip[1]) << 16) + (Long.parseLong(ip[2]) << 8) + Long.parseLong(ip[3]);
    }

    /**
     * 將十進位制整數形式轉換成127.0.0.1形式的ip地址
     * 將整數形式的IP地址轉化成字串的方法如下:
     * 1、將整數值進行右移位操作(>>>),右移24位,右移時高位補0,得到的數字即為第一段IP。
     * 2、通過與操作符(&)將整數值的高8位設為0,再右移16位,得到的數字即為第二段IP。
     * 3、通過與操作符吧整數值的高16位設為0,再右移8位,得到的數字即為第三段IP。
     * 4、通過與操作符吧整數值的高24位設為0,得到的數字即為第四段IP。
     * @param longIp
     * @return
     */
    public static String longToIP(long longIp) {
        StringBuffer sb = new StringBuffer("");
        // 直接右移24位
        sb.append(String.valueOf((longIp >>> 24)));
        sb.append(".");
        // 將高8位置0,然後右移16位
        sb.append(String.valueOf((longIp & 0x00FFFFFF) >>> 16));
        sb.append(".");
        // 將高16位置0,然後右移8位
        sb.append(String.valueOf((longIp & 0x0000FFFF) >>> 8));
        sb.append(".");
        // 將高24位置0
        sb.append(String.valueOf((longIp & 0x000000FF)));
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(ipToLong("219.239.110.138"));
        System.out.println(longToIP(18537472));
    }
}

ip查詢類的實現

package IpRange;

import java.io.*;
import java.util.LinkedList;

public class IpRange {

/**
*
*@author ***
*@date
*二分查詢法
*/
    public static MyIp getIpCode(String ip){

        MyIp[] myIps=getmyip();
        if(myIps==null||myIps.length==0) return null;
        long iplong=IPUtils.ipToLong(ip);
        if(iplong<myIps[0].getStartIP()||iplong>myIps[myIps.length-1].getEndIP()) return null;
        int left=0;
        int right=myIps.length-1;
        int mid=(left+right)/2;
        while (left<=right){

            if(iplong<myIps[mid].getStartIP()) right=mid-1;

            if(iplong>myIps[mid].getStartIP()) left=mid+1;

            if(iplong>=myIps[mid].getStartIP()&&iplong<=myIps[mid].getEndIP()) return myIps[mid];

            mid=(left+right)/2;

        }
        return null;

    }
    /**
    *@author
    *@date
    *讀取檔案轉換成MyIp物件
    */
    public static MyIp[] getmyip(){
        InputStreamReader inputStreamReader=null;
        BufferedReader bufferedReader=null;
        File file=new File("E:\\aaa\\iprule");
        try {
            inputStreamReader=new InputStreamReader(new FileInputStream(file),"UTF-8");

            bufferedReader=new BufferedReader(inputStreamReader);

            String line;

            LinkedList<MyIp> linkedList=new LinkedList<MyIp>();

            while ((line=bufferedReader.readLine())!=null){

                String[] ipranges=line.split(",");


                linkedList.add(new MyIp(IPUtils.ipToLong(ipranges[0]),IPUtils.ipToLong(ipranges[1]),ipranges[2]));
            }
            MyIp[] myIps=linkedList.toArray(new MyIp[]{});
            return myIps;

        } catch (IOException e) {
            e.printStackTrace();
        }
    return null;
    }

    public static void main(String[] args) {

        MyIp myIp=getIpCode("1.2.16.15");

        String code=myIp.getCode();
        System.out.println("你所在的城市為:"+code);


    }
}