使用二分查詢法,查詢ip所在的範圍對應的code(語言為java\scala\python) java語言來實現
阿新 • • 發佈:2018-12-18
- 使用二分法實現查詢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); } }