今天拿到個需求要搜索ip地址匹配時候需要匹配網段中的IP,靠network網段地址後面的掩碼長度計算是否包含某個ip,這種事情,我們每次都是網上找個在線計算器算一下, 不過想了想這麼多策略包含太多的網段,有的是這種場景需要查詢某個ip是否在某個網段中,所以理了理思路寫個方法
1、網段地址,可以根據掩碼長度來計算出來主機範圍,
我們的掩碼格式:ip/mask-length 即:172.30.28.0/24,很標準的使用網段網關地址/子網掩碼來表示,
2、計算給定IP的二進制地址,判斷主機位是否在這個網段中
寫個方法試試看:
/**
* 判斷給定IP地址是否在指定網段中
* network eg:172.30.29.0/25
* ip eg: 172.30.29.129
* @param network
* @param ip
* @return
*/
public Boolean isContains(String network, String ip) {
String[] networkArr = network.split("/");
String networkBin = transIpToBrinary(networkArr[0]);
String ipBin = transIpToBrinary(ip);
int mask = Integer.parseInt(networkArr[1]);
//如果掩碼長度不在1-32之間,就直接比較倆地址吧
if (mask < 0 || mask >= 32)
return ip.equals(network);
//這一步實際是想求ip地址的大段,沒想好怎麼算,就先這樣算了
int targetMask = mask / 8;
int newMask = targetMask * 8;
//根據network地址求出網段中最大的主機地址
// (這裏包含廣播地址,既然是匹配IP是否在此網段中,就未對廣播地址及網關地址清除)
StringBuilder networkMaxHostBuilder = new StringBuilder();
networkMaxHostBuilder.append(networkBin, 0, mask); //取網絡位
for (int i = mask; i < 32; i++) {
networkMaxHostBuilder.append("1"); // 主機位補上1,這就拼成了此網段中最大主機地址
}
//截取主機位轉換爲十進制,進行比較
int networkMinHost = Integer.parseInt(networkBin.substring(newMask, 32), 2);
int networkMaxHost = Integer.parseInt(networkMaxHostBuilder.substring(newMask, 32), 2);
int ipBinary = Integer.parseInt(ipBin.substring(newMask, 32), 2);
//網絡位要相等
if (networkBin.substring(0, newMask).equals(ipBin.substring(0, newMask))) {
//且必須在主機地址中
if (ipBinary >= networkMinHost && ipBinary <= networkMaxHost)
return true;
}
return false;
}
/**
* 轉換ip地址
* @param ip
* @return
*/
private String transIpToBrinary(String ip) {
String[] ipArr = ip.split("\\.");
String net;
StringBuilder netBuilder = new StringBuilder();
int ipLen = ipArr.length;
for (int i = 0; i < ipLen; i++) {
net = doTransToBinary(ipArr[i]);
netBuilder.append(net);
}
return netBuilder.toString();
}
/**
* 轉換十進制爲二進制
* @param ip
* @return
*/
private String doTransToBinary(String ip) {
int numInt = Integer.parseInt(ip);
StringBuilder binaryBuilder = new StringBuilder();
for (int i = 7; i >= 0; i--) {
int binary = numInt >>> i & 1;
binaryBuilder.append(binary);
}
return binaryBuilder.toString();
}
測試了幾遍,沒啥問題,如果有更好的思路和實現方法,麻煩提供一下,謝謝啦,
就先這樣了,寫的很急,也沒來的及優化,捕獲異常,變量名標準之類的,各位看官如果需要,記得捕獲異常優化一下然後多測幾遍,我得下班了。