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地址範圍與網絡地址/子網掩碼的轉換,點分十進制與數字掩碼的轉換
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.