IPv4 地址字符串(如 "192.168.1.1")轉換為 32 位長整型,便於數據庫存儲、範圍查詢、位運算處理。本文提供帶格式校驗的標準實現。
/**
* IP 字符串轉長整型(大端序/網絡字節序)
* @param ip 標準 IPv4 格式,如 "192.168.1.1"
* @return 32 位無符號整數值(Java long 承載)
* @throws IllegalArgumentException 格式非法
*/
public static long ip2Long(final String ip) {
if (ip == null || ip.isEmpty()) {
throw new IllegalArgumentException("IP 不能為空");
}
// 正則校驗:四段 1-3 位數字,每段 0-255(此處僅校驗格式,數值範圍由 parseLong 隱含)
if (!ip.matches("(\\d{1,3}\\.){3}\\d{1,3}")) {
throw new IllegalArgumentException("[" + ip + "] 不是有效的 IPv4 地址格式");
}
String[] octets = ip.split("\\.");
return ((Long.parseLong(octets[0]) & 0xFFL) << 24) |
((Long.parseLong(octets[1]) & 0xFFL) << 16) |
((Long.parseLong(octets[2]) & 0xFFL) << 8) |
((Long.parseLong(octets[3]) & 0xFFL));
}
& 0xFFL: 防止負數擴展符號位,確保每段視為無符號 8 位| 合併: 無進位干擾,等價於加法但語義更清晰long: Java 無無符號 int,用 long 承載 0 ~ 4,294,967,295
public static long ip2LongStrict(String ip) {
String[] octets = ip.split("\\.");
if (octets.length != 4) throw new IllegalArgumentException("IP 段數不為 4");
long result = 0;
for (int i = 0; i < 4; i++) {
int val = Integer.parseInt(octets[i]);
if (val < 0 || val > 255) {
throw new IllegalArgumentException("IP 段超出範圍: " + val);
}
result = (result << 8) | (val & 0xFF);
}
return result;
}
public static String long2Ip(long ip) {
return ((ip >> 24) & 0xFF) + "." +
((ip >> 16) & 0xFF) + "." +
((ip >> 8) & 0xFF) + "." +
(ip & 0xFF);
}
INT UNSIGNED 存儲 IP,索引範圍查詢:WHERE ip_num BETWEEN ip2Long('192.168.1.0') AND ip2Long('192.168.1.255')ZSET 以 IP 長整型為 score,實現 IP 段排序(ip & mask) == network高頻調用可避免正則與分割開銷,手寫解析循環:
public static long ip2LongFast(String ip) {
long result = 0;
int val = 0;
for (char c : ip.toCharArray()) {
if (c == '.') {
result = (result << 8) | val;
val = 0;
} else {
val = val * 10 + (c - '0');
}
}
return (result << 8) | val; // 最後一段
}