Subnet / CIDR Calculator — Java source
Compute IPv4 subnet details from a CIDR block - network, broadcast, host range, netmask, wildcard, host count, IP class, and private-range detection. Split a block into smaller subnets, all in your browser.
This is the Java implementation — the same logic the interactive tool runs, in a shareable, citable form.
// subnet-cidr — Java port: IPv4 subnet/CIDR math (dotted-quad ⇄ uint32-as-long, subnet details, CIDR splitting). Language: Java (17+). Port of src/lib/subnet-cidr.ts — same logic as this dir's python.py / go.go; invalid input yields null rather than throwing.
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public final class SubnetCidr {
/** Computed properties of a CIDR block — mirrors SubnetInfo in the TS lib. */
public record SubnetInfo(String network, String broadcast, String firstHost, String lastHost,
long hostCount, int prefix, char ipClass, boolean isPrivate) {}
/** The TS /^\d+$/ check — rejects signs, hex, whitespace, and the empty string. */
static boolean allDigits(String s) {
if (s.isEmpty()) return false;
for (int i = 0; i < s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return false;
return true;
}
/** "a.b.c.d" → unsigned 32-bit value carried in a long. null for malformed input. */
static Long ipToInt(String ip) {
String[] parts = ip.split("\\.", -1);
if (parts.length != 4) return null;
long result = 0;
for (String part : parts) {
if (!allDigits(part) || part.length() > 3) return null;
long octet = Long.parseLong(part);
if (octet > 255) return null;
result = result * 256 + octet;
}
return result & 0xFFFFFFFFL;
}
static String intToIp(long n) {
long v = n & 0xFFFFFFFFL;
return String.format(Locale.ROOT, "%d.%d.%d.%d", v >> 24, (v >> 16) & 255, (v >> 8) & 255, v & 255);
}
static long maskFromPrefix(int p) { return p == 0 ? 0 : (0xFFFFFFFFL << (32 - p)) & 0xFFFFFFFFL; }
/** "ip/prefix" → full block details; null for an invalid CIDR. */
public static SubnetInfo subnetDetails(String cidr) {
int slash = cidr.indexOf('/');
if (slash < 0) return null;
String prefixPart = cidr.substring(slash + 1);
if (prefixPart.indexOf('/') >= 0 || !allDigits(prefixPart) || prefixPart.length() > 2) return null;
int prefix = Integer.parseInt(prefixPart);
Long ip = ipToInt(cidr.substring(0, slash));
if (prefix > 32 || ip == null) return null;
long mask = maskFromPrefix(prefix), network = ip & mask, broadcast = network | ~mask & 0xFFFFFFFFL;
// /31 (point-to-point) and /32 (single host) have no host/broadcast split.
long first = prefix >= 31 ? network : network + 1;
long last = prefix >= 31 ? broadcast : broadcast - 1;
long hosts = prefix >= 32 ? 1 : prefix == 31 ? 2 : (1L << (32 - prefix)) - 2;
long o1 = network >>> 24, o2 = (network >>> 16) & 255;
char klass = o1 < 128 ? 'A' : o1 < 192 ? 'B' : o1 < 224 ? 'C' : '-'; // D/E → '-'
boolean priv = o1 == 10 || (o1 == 172 && o2 >= 16 && o2 <= 31) || (o1 == 192 && o2 == 168);
return new SubnetInfo(intToIp(network), intToIp(broadcast), intToIp(first), intToIp(last),
hosts, prefix, klass, priv);
}
/** Split into 2^(newPrefix-prefix) children; empty list for invalid input or range. */
public static List<String> splitSubnet(String cidr, int newPrefix) {
SubnetInfo base = subnetDetails(cidr);
if (base == null || newPrefix < base.prefix() || newPrefix > 32) return List.of();
long network = ipToInt(base.network()) & maskFromPrefix(base.prefix());
long block = 1L << (32 - newPrefix);
List<String> out = new ArrayList<>(1 << (newPrefix - base.prefix()));
for (int i = 0; i < (1 << (newPrefix - base.prefix())); i++)
out.add(intToIp(network + i * block) + "/" + newPrefix);
return out;
}
public static void main(String[] args) {
SubnetInfo d = subnetDetails("192.168.1.100/24");
System.out.printf("192.168.1.100/24 net=%s bcast=%s first=%s last=%s hosts=%d class=%s private=%s%n",
d.network(), d.broadcast(), d.firstHost(), d.lastHost(), d.hostCount(), d.ipClass(), d.isPrivate());
for (String kid : splitSubnet("192.168.1.0/24", 26)) System.out.println(" split /26 → " + kid);
}
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →