package net.shadowfacts.phycon.api.util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author shadowfacts */ public final class IPAddress { @NotNull public static IPAddress random(@NotNull Random random) { int value = 0; // don't accidentally generate reserved, broadcast, or loopback addresses while (value == 0 || value == 0xff_ff_ff_ff || (value >> 24) == 127) { value = random.nextInt(); } return new IPAddress(value); } private static final Random ipAddressRandom = new Random(); @NotNull public static IPAddress random() { return random(ipAddressRandom); } private static final Pattern IP_PATTERN = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"); @Nullable public static IPAddress parse(String s) { Matcher matcher = IP_PATTERN.matcher(s); if (!matcher.matches()) { return null; } int a = Integer.parseInt(matcher.group(1)); int b = Integer.parseInt(matcher.group(2)); int c = Integer.parseInt(matcher.group(3)); int d = Integer.parseInt(matcher.group(4)); if (a > 255 || b > 255 || c > 255 || d > 255) { return null; } return new IPAddress(a, b, c, d); } public static final IPAddress BROADCAST = new IPAddress(0xff_ff_ff_ff); public final int address; public IPAddress(int address) { if (address == 0) { throw new RuntimeException("IP address 0.0.0.0 is reserved"); } this.address = address; } public IPAddress(int a, int b, int c, int d) { this(((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)); } /** * @return If this IP address is a broadcast address (255.255.255.255). */ public boolean isBroadcast() { return address == 0xff_ff_ff_ff; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IPAddress ipAddress = (IPAddress) o; return address == ipAddress.address; } @Override public int hashCode() { return address; } @Override public String toString() { StringBuilder builder = new StringBuilder(); for (int i = 3; i >= 0; i--) { if (i < 3) { builder.append('.'); } int octet = (address >> (i * 8)) & 0xff; builder.append(octet); } return builder.toString(); } }