private static final int IPV4BYTES = 4; // IPv4字节数为4
private static final int BYTEBITS = 8; // 每个字节的比特位长度为8
/* IPv4,计算一个地址范围所属最小"网络地址/子网掩码"
例:1.1.0.1-1.1.3.10或者1.1.3.10-1.1.0.1
1.1.0.1: 00000001 00000001 00000001 00000001
1.1.3.10:00000001 00000001 00000011 00001010
从左至右找到第一个不同所在位置,得到子网掩码为22
将子网掩码后面的位数置为0,得到网络地址1.1.0.0
返回1.1.0.0/22
*/
public static String getNetworkAddressAndNumMask(String startAddress, String endAddress) {
String networkAddress = "";
int mask = 0;
// 用.分隔起始地址和结束地址,并将String型数组转为int型数组
String[] startStrArr = startAddress.split("\\.");
int[] startNums = Arrays.asList(startStrArr).stream().mapToInt(Integer::parseInt).toArray();
String[] endStrArr = endAddress.split("\\.");
int[] endNums = Arrays.asList(endStrArr).stream().mapToInt(Integer::parseInt).toArray();
// 计算子网掩码
for (int i = 0; i < IPV4BYTES; i++) {
int xorValue = startNums[i] ^ endNums[i]; // 异或操作
if (xorValue > 0) {
for (int j = 1; j <= BYTEBITS; j++) {
if ((xorValue >>> j) == 0) { // 右移直至为0
mask += (BYTEBITS - j); // 8减右移位数为网络位
break;
}
}
} else { // 如果异或值为0,则目前的8位为网络位
mask += BYTEBITS;
}
}
// 计算网络地址
int[] networkNums = new int[IPV4BYTES];
for (int i = 0; i < IPV4BYTES; i++) {
if (mask / BYTEBITS > i) {
networkNums[i] = startNums[i];
} else if (mask / BYTEBITS == i) {
networkNums[i] = startNums[i] & (255 << (BYTEBITS - mask % BYTEBITS));
} else {
networkNums[i] = 0;
}
}
networkAddress = StringUtils.join(networkNums, ".");
return networkAddress + "/" + mask;
}
/* IPv4,计算一个地址范围所属最小"网络地址 点分十进制掩码"
例:1.1.0.1-1.1.3.10返回1.1.0.0 255.255.252.0
*/
public static String getNetworkAddressAndDottedDecimalMask(String startAddress, String endAddress) {
String networkMask = getNetworkAddressAndNumMask(startAddress, endAddress);
String networkAddress = networkMask.split("/")[0]; // 网络地址
int numMask = Integer.parseInt(networkMask.split("/")[1]); // 子网掩码,数字
String dottedDecimalMask = numMaskToDottedDecimalMask(numMask); // 子网掩码,点分十进制
return networkAddress + " " + dottedDecimalMask;
}
// IPv4,将子网掩码数字转为点分十进制
public static String numMaskToDottedDecimalMask(int numMask) {
int[] networkNums = new int[IPV4BYTES];
for (int i = 0; i < IPV4BYTES; i++) {
if (numMask / BYTEBITS > i) {
networkNums[i] = 255;
} else if (numMask / BYTEBITS == i) {
networkNums[i] = (255 << (BYTEBITS - numMask % BYTEBITS)) & 255;
} else {
networkNums[i] = 0;
}
}
return StringUtils.join(networkNums, ".");
}
// IPv4,将子网掩码点分十进制转为数字
public static int dottedDecimalMaskToNumMask(String dottedDecimalMask) {
int numMask = 0;
String[] maskStr = dottedDecimalMask.split("\\.");
int[] maskInt = Arrays.asList(maskStr).stream().mapToInt(Integer::parseInt).toArray();
for (int i = 0; i < IPV4BYTES && maskInt[i] > 0; i++) {
for (int j = 1; j <= BYTEBITS; j++) {
if ((maskInt[i] << j & 255) == 0) { // 左移,直至遇到0
numMask += j;
}
}
}
return numMask;
}
IPv4地址范围与网络地址/子网掩码的转换,点分十进制与数字掩码的转换
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.