以Java语言实现,主要针对IPv4地址。用于处理本机ip获取和ip是否归属同一网段校验。
工具类源码如下:
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
/**
* IPV4工具类
*
* @author jun.chen
*
*/
@Slf4j
public class IPV4Util {
private static InetAddress getLocalHost() throws UnknownHostException {
return Inet4Address.getLocalHost();
}
/**
* 获取本机IP
*
* @return
* @throws UnknownHostException
*/
public static String getHostAddress() throws UnknownHostException {
return getLocalHost().getHostAddress();
}
/**
* 获取本机子网掩码
*
* @return
* @throws UnknownHostException
* @throws SocketException
*/
public static String getMaskAddress() throws UnknownHostException, SocketException {
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(getLocalHost());
String maskAddress = "";
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = address.getBroadcast();
if (broadcast instanceof Inet4Address) {
short mask = address.getNetworkPrefixLength();
maskAddress = getMaskAddress(mask);
}
}
return maskAddress;
}
/**
* 判断是否同一网段
*
* @param sourceAddress
* @return
* @throws UnknownHostException
* @throws SocketException
*/
public static boolean isLocalAreaNetwork(String sourceAddress) throws UnknownHostException, SocketException {
int sourceValue = getAddressValue(sourceAddress);
Map<String, List<String>> allAddressMap = getAllAddressMap();
for (Entry<String, List<String>> entry : allAddressMap.entrySet()) {
String maskAddress = entry.getKey();
int maskValue = getAddressValue(maskAddress);
for (String hostAddress : entry.getValue()) {
int hostValue = getAddressValue(hostAddress);
boolean equal = (maskValue & hostValue) == (maskValue & sourceValue);
log.debug("boolean:{} mask:{} local:{} source:{}", equal, maskAddress, hostAddress, sourceAddress);
if (equal) {
return equal;
}
}
}
return false;
}
private static String getMaskAddress(short maskLength) {
String[] maskIps = new String[4];
for (int i = 0; i < maskIps.length; i++) {
int node = (maskLength >= 8) ? 255 : (maskLength > 0 ? (maskLength & 0xff) : 0);
maskIps[i] = String.valueOf(node);
maskLength -= 8;
}
return String.join(".", maskIps);
}
private static Map<String, List<String>> hostAddressMapping;
private static Map<String, List<String>> getAllAddressMap() throws SocketException, UnknownHostException {
if (null != hostAddressMapping) {
return hostAddressMapping;
}
log.debug("初始化当前主机子网掩码和IP的关系");
hostAddressMapping = new HashMap<>();
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
List<InterfaceAddress> addressList = new ArrayList<>();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface nextElement = networkInterfaces.nextElement();
for (InterfaceAddress address : nextElement.getInterfaceAddresses()) {
InetAddress broadcast = address.getBroadcast();
if (broadcast instanceof Inet4Address) {
addressList.add(address);
}
}
}
Map<Short, List<InterfaceAddress>> groupAddress = addressList.stream()
.collect(Collectors.groupingBy(InterfaceAddress::getNetworkPrefixLength));
for (Entry<Short, List<InterfaceAddress>> entry : groupAddress.entrySet()) {
List<String> list = entry.getValue().stream().map(a -> a.getAddress().getHostAddress())
.collect(Collectors.toList());
hostAddressMapping.put(getMaskAddress(entry.getKey()), list);
}
log.debug("初始化关系完成");
return hostAddressMapping;
}
private static int getAddressValue(String address) {
byte[] addr = getAddressBytes(address);
int address1 = addr[3] & 0xFF;
address1 |= ((addr[2] << 8) & 0xFF00);
address1 |= ((addr[1] << 16) & 0xFF0000);
address1 |= ((addr[0] << 24) & 0xFF000000);
return address1;
}
private static byte[] getAddressBytes(String address) {
String[] addrs = address.split("\\.");
int length = addrs.length;
byte[] addr = new byte[length];
for (int index = 0; index < length; index++) {
addr[index] = (byte) (Integer.valueOf(addrs[index]) & 0xff);
}
return addr;
}
}
测试主函数:
public static void main(String[] args) throws UnknownHostException, SocketException {
String IP = "192.168.148.6";
System.out.println(String.format("IP:%s 是否处于当前局域网:%s", IP, IPV4Util.isLocalAreaNetwork(IP)));
IP = "127.0.0.1";
System.out.println(String.format("IP:%s 是否处于当前局域网:%s", IP, IPV4Util.isLocalAreaNetwork(IP)));
IP = "192.168.1.1";
System.out.println(String.format("IP:%s 是否处于当前局域网:%s", IP, IPV4Util.isLocalAreaNetwork(IP)));
}
测试截图:
对于是否归属统一网段有其他好的建议的欢迎留言。