1.情景展示
當我們需要將IP存進mysql數據庫的時候,數據庫的設計是:建議我們存入IP轉換成的數值。
作者建議當存儲IPv4地址時,應該使用32位的無符號整數(UNSIGNED INT)來存儲IP地址,而不是使用字符串。
相對字符串存儲,使用無符號整數來存儲有如下的好處:
- 節省空間,不管是數據存儲空間,還是索引存儲空間;
- 便於使用范圍查詢(BETWEEN...AND),且效率更高。
使用無符號整數來存儲也有缺點:
- 不便於閱讀
- 需要手動轉換
對於轉換來說,MySQL提供了相應的函數來把字符串格式的IP轉換成整數INET_ATON(),以及把整數格式的IP轉換成字符串的INET_NTOA()。
下面講一下,如何使用java實現IP和數值之前的轉換?
2.方式一
查看代碼
/**
* 把字符串IP轉換成long
* @param ipStr 字符串IP
* @return IP對應的long值
*/
public static long ip2Long(@NotNull String ipStr) {
String[] ip = ipStr.split("\\.");
return (Long.valueOf(ip[0]) << 24) + (Long.valueOf(ip[1]) << 16)
+ (Long.valueOf(ip[2]) << 8) + Long.valueOf(ip[3]);
}
/**
* 把IP的long值轉換成字符串
* @param ipLong IP的long值
* @return long值對應的字符串
*/
@NotNull
public static String long2Ip(long ipLong) {
StringBuilder ip = new StringBuilder();
ip.append(ipLong >>> 24).append(".");
ip.append((ipLong >>> 16) & 0xFF).append(".");
ip.append((ipLong >>> 8) & 0xFF).append(".");
ip.append(ipLong & 0xFF);
return ip.toString();
}
3.方式二
查看代碼
public static Long convertIPv4(String ipStr) {
if (ipStr != null && !ipStr.isEmpty()) {
try {
String[] ipTokens = ipStr.split("\\.");
if (ipTokens.length != 4) {
throw new IllegalArgumentException("IP字符串錯誤:" + ipStr);
} else {
long ipNum = 0L;
for(int i = 0; i < 4; ++i) {
ipNum = (ipNum << 8) + (long)Integer.parseInt(ipTokens[i]);
}
return ipNum;
}
} catch (RuntimeException var5) {
log.error("IP轉換錯誤:" + ipStr, var5);
throw var5;
}
} else {
return null;
}
}
public static String convertIPv4(long ipNum) {
return (ipNum >>> 24) + "." + ((ipNum & 16777215L) >>> 16) + "." + ((ipNum & 65535L) >>> 8) + "." + (ipNum & 255L);
}