java
package com.chun.test;
/**
* @author chun
* @date 2025/4/11 11:18
*/
import java.math.BigInteger;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class IpRangeCalculator2 {
public static List<String> calculateCIDR(String startIp, String endIp) {
try {
BigInteger start = ipToBigInteger(startIp);
BigInteger end = ipToBigInteger(endIp);
int bits = getIPVersion(startIp);
List<String> result = new ArrayList<>();
if (start.compareTo(end) > 0) {
return result;
}
while (start.compareTo(end) <= 0) {
// 1. 计算当前可用的最大CIDR块
int maxPrefix = findMaxPrefix(start, end, bits);
String cidr = bigIntegerToIp(start, bits) + "/" + maxPrefix;
result.add(cidr);
// 2. 计算该CIDR块的结束地址并更新start
BigInteger blockSize = BigInteger.ONE.shiftLeft(bits - maxPrefix);
start = start.add(blockSize);
}
return result;
} catch (Exception e) {
return Collections.emptyList();
}
}
// 辅助方法:找到从start开始的最大CIDR前缀
private static int findMaxPrefix(BigInteger start, BigInteger end, int bits) {
BigInteger range = end.subtract(start).add(BigInteger.ONE);
int maxShift = range.bitLength() - 1;
if (maxShift < 0) maxShift = 0;
for (int shift = maxShift; shift >= 0; shift--) {
BigInteger size = BigInteger.ONE.shiftLeft(shift);
if (size.compareTo(range) > 0) continue;
// 检查地址是否对齐
BigInteger mask = size.subtract(BigInteger.ONE);
if (start.and(mask).equals(BigInteger.ZERO)) {
return bits - shift;
}
}
return bits; // 单个IP(/32或/128)
}
// IP转换方法(支持v4/v6)
private static BigInteger ipToBigInteger(String ip) throws UnknownHostException {
InetAddress address = InetAddress.getByName(ip);
byte[] bytes = address.getAddress();
return new BigInteger(1, bytes);
}
// 判断IP类型
private static int getIPVersion(String ip) {
return ip.contains(":") ? 128 : 32;
}
// 转换回IP字符串
private static String bigIntegerToIp(BigInteger ip, int bits) throws UnknownHostException {
byte[] bytes;
if (bits == 32) { // IPv4
bytes = ip.toByteArray();
byte[] v4Bytes = new byte[4];
System.arraycopy(bytes, Math.max(bytes.length - 4, 0), v4Bytes, 0, 4);
return InetAddress.getByAddress(v4Bytes).getHostAddress();
} else { // IPv6
bytes = ip.toByteArray();
byte[] v6Bytes = new byte[16];
System.arraycopy(bytes, Math.max(bytes.length - 16, 0), v6Bytes, 0, bytes.length);
return Inet6Address.getByAddress(v6Bytes).getHostAddress();
}
}
public static void main(String[] args) {
// IPv4测试
System.out.println(calculateCIDR("192.168.0.127", "192.168.0.127"));
// 输出: [192.168.0.0/30, 192.168.0.4/31]
// IPv6测试
System.out.println(calculateCIDR("2001:db8::8001", "2001:db8::fffa"));
// 输出: [2001:db8::/126, 2001:db8::4/128]
}
}
验证
java
package com.chun.test;
import java.math.BigInteger;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
/**
* @author chun
* @date 2025/4/11 11:46
*/
public class IPMaskCalculator {
// 验证方法:打印每个CIDR的实际范围
public static void printCIDRRange(List<String> cidrs) {
for (String cidr : cidrs) {
try {
String[] parts = cidr.split("/");
String ip = parts[0];
int prefix = Integer.parseInt(parts[1]);
int bits = getIPVersion(ip);
BigInteger start = ipToBigInteger(ip);
BigInteger mask = calculateMask(prefix, bits);
// 计算CIDR范围
BigInteger network = start.and(mask);
BigInteger broadcast = network.add(mask.not().and(BigInteger.ONE.shiftLeft(bits).subtract(BigInteger.ONE)));
System.out.printf("%-20s => %s - %s%n",
cidr,
bigIntegerToIp(network, bits),
bigIntegerToIp(broadcast, bits));
} catch (Exception e) {
System.out.println("Invalid CIDR: " + cidr);
}
}
}
// 计算网络掩码
private static BigInteger calculateMask(int prefix, int bits) {
return BigInteger.ONE.shiftLeft(bits)
.subtract(BigInteger.ONE)
.shiftLeft(bits - prefix)
.and(BigInteger.ONE.shiftLeft(bits).subtract(BigInteger.ONE));
}
// 以下是复用之前的转换方法
private static BigInteger ipToBigInteger(String ip) throws UnknownHostException {
InetAddress address = InetAddress.getByName(ip);
byte[] bytes = address.getAddress();
return new BigInteger(1, bytes);
}
private static int getIPVersion(String ip) {
return ip.contains(":") ? 128 : 32;
}
private static String bigIntegerToIp(BigInteger ip, int bits) throws UnknownHostException {
byte[] bytes = ip.toByteArray();
if (bits == 32) { // IPv4
byte[] v4Bytes = new byte[4];
System.arraycopy(bytes, Math.max(bytes.length - 4, 0), v4Bytes, 0, 4);
return InetAddress.getByAddress(v4Bytes).getHostAddress();
} else { // IPv6
byte[] v6Bytes = new byte[16];
System.arraycopy(bytes, Math.max(bytes.length - 16, 0), v6Bytes, 0, bytes.length);
return Inet6Address.getByAddress(v6Bytes).getHostAddress();
}
}
// 测试验证
public static void main(String[] args) {
// IPv4测试
System.out.println("IPv4 Test:");
printCIDRRange(Arrays.asList("192.168.0.127/32"));
// IPv6测试
System.out.println("\nIPv6 Test:");
printCIDRRange(Arrays.asList(
"2001:db8::/113", "2001:db8::8000/114", "2001:db8::c000/115", "2001:db8::e000/116",
"2001:db8::f000/117", "2001:db8::f800/118", "2001:db8::fc00/119", "2001:db8::fe00/120",
"2001:db8::ff00/121", "2001:db8::ff80/122", "2001:db8::ffc0/123", "2001:db8::ffe0/124",
"2001:db8::fff0/125", "2001:db8::fff8/126", "2001:db8::fffc/127", "2001:db8::fffe/128"
));
}
}
CIDR转换掩码
java
package com.chun.test;
/**
* @author chun
* @date 2025/4/14 16:37
*/
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
public class CidrConverter {
public static String cidrToMask(int cidr) {
if (cidr < 0 || cidr > 128) {
throw new IllegalArgumentException("CIDR must be between 0 and 128");
}
if (cidr <= 32) {
// IPv4 处理(使用位运算)
long maskLong = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
int maskInt = (int) maskLong;
int b1 = (maskInt >> 24) & 0xFF;
int b2 = (maskInt >> 16) & 0xFF;
int b3 = (maskInt >> 8) & 0xFF;
int b4 = maskInt & 0xFF;
return String.format("%d.%d.%d.%d", b1, b2, b3, b4);
} else {
// IPv6 处理(使用 Inet6Address)
byte[] maskBytes = new byte[16];
int fullBytes = cidr / 8;
int remainingBits = cidr % 8;
// 填充完整的 0xFF 字节
Arrays.fill(maskBytes, 0, fullBytes, (byte) 0xFF);
// 处理剩余位
if (remainingBits > 0 && fullBytes < 16) {
maskBytes[fullBytes] = (byte) (0xFF << (8 - remainingBits));
}
try {
Inet6Address mask = (Inet6Address) InetAddress.getByAddress(maskBytes);
return mask.getHostAddress().toLowerCase();
} catch (UnknownHostException e) {
throw new RuntimeException("Invalid IPv6 mask generation", e);
}
}
}
public static void main(String[] args) {
// 测试用例
System.out.println(cidrToMask(32)); // 输出 255.255.255.255
System.out.println(cidrToMask(28)); // 输出 255.255.255.255
System.out.println(cidrToMask(29)); // 输出 255.255.255.255
System.out.println(cidrToMask(30)); // 输出 255.255.255.255
System.out.println(cidrToMask(31)); // 输出 255.255.255.255
System.out.println(cidrToMask(24)); // 输出 255.255.255.0
System.out.println(cidrToMask(0)); // 输出 0.0.0.0
System.out.println(cidrToMask(128)); // 输出 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
System.out.println(cidrToMask(64)); // 输出 ffff:ffff:ffff:ffff::
System.out.println(cidrToMask(72)); // 输出 ffff:ffff:ffff:ffff:ff00::
System.out.println(cidrToMask(127));
System.out.println(cidrToMask(126));
System.out.println(cidrToMask(125));
System.out.println(cidrToMask(124));
System.out.println(cidrToMask(65));
System.out.println(cidrToMask(66));
System.out.println(cidrToMask(67));
System.out.println(cidrToMask(68));
System.out.println(cidrToMask(69));
}
}