I have a simple class for representing IPv4-addresses via int
values, and a simple IP-address filter that works like a set of IPv4-addresses.
com.github.coderodde.util.net.IPv4Address.java:
package com.github.coderodde.util.net;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class implements IPv4 addresses.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Mar 21, 2023)
* @since 1.6 (Mar 21, 2023)
*/
public class IPv4Address {
private final int addressInt;
private String addressString;
private static final String ADDRESS_REGEX =
"[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}";
private static final Pattern ADDRESS_PATTERN = Pattern.compile(ADDRESS_REGEX);
public IPv4Address(String addressString) {
checkAddressString(addressString);
this.addressInt = toInt(addressString);
this.addressString = toAddressString(addressInt);
}
@Override
public String toString() {
return addressString;
}
@Override
public boolean equals(Object o) {
IPv4Address other = (IPv4Address) o;
return addressInt == other.addressInt;
}
@Override
public int hashCode() {
return addressInt;
}
private static String toAddressString(int address) {
StringBuilder stringBuilder = new StringBuilder();
int b0 = address & 0xff;
int b1 = (address & 0xff00) >> 8;
int b2 = (address & 0xff0000) >> 16;
int b3 = (address & 0xff000000) >>> 24;
stringBuilder.append(b3)
.append(".")
.append(b2)
.append(".")
.append(b1)
.append(".")
.append(b0);
return stringBuilder.toString();
}
private static int toInt(String addressString) {
addressString = addressString.trim();
checkAddressString(addressString);
String[] addressStringParts = addressString.split("\\.");
int b0 = Integer.parseInt(addressStringParts[3]);
int b1 = Integer.parseInt(addressStringParts[2]);
int b2 = Integer.parseInt(addressStringParts[1]);
int b3 = Integer.parseInt(addressStringParts[0]);
return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
}
private static void checkAddressString(String addressString) {
Matcher matcher = ADDRESS_PATTERN.matcher(addressString);
if (!matcher.matches()) {
throw new IllegalArgumentException(
"The input string '"
+ addressString
+ "' is definitely an IPv4 address.");
}
String[] parts = addressString.split("\\.");
int b0 = Integer.parseInt(parts[0]);
int b1 = Integer.parseInt(parts[1]);
int b2 = Integer.parseInt(parts[2]);
int b3 = Integer.parseInt(parts[3]);
checkByte(b0, "Byte " + b0 + " is not within the range [0, 255].");
checkByte(b1, "Byte " + b1 + " is not within the range [0, 255].");
checkByte(b2, "Byte " + b2 + " is not within the range [0, 255].");
checkByte(b3, "Byte " + b3 + " is not within the range [0, 255].");
}
private static void checkByte(int byteInt, String exceptionMessage) {
if (byteInt > 255) {
throw new IllegalArgumentException(exceptionMessage);
}
}
}
com.github.coderodde.util.net.IPFilter.java:
package com.github.coderodde.util.net;
import java.util.HashMap;
import java.util.Map;
/**
* This class implements a IPv4-address filter.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Mar 21, 2023)
* @since 1.6 (Mar 21, 2023)
*/
public class IPFilter {
private final Map<String, IPv4Address> table = new HashMap<>();
public void add(IPv4Address address) {
table.put(address.toString(), address);
}
public void add(String addressString) {
table.put(addressString, new IPv4Address(addressString));
}
public void remove(IPv4Address address) {
table.remove(address.toString());
}
public void remove(String addressString) {
table.remove(addressString);
}
public boolean contains(IPv4Address address) {
return table.containsKey(address.toString());
}
public boolean contains(String addressString) {
return table.containsKey(addressString);
}
public int size() {
return table.size();
}
public boolean isEmpty() {
return table.isEmpty();
}
}
com.github.coderodde.util.net.IPv4AddressTest.java:
package com.github.coderodde.util.net;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public final class IPv4AddressTest {
@Test
public void test() {
IPv4Address a = new IPv4Address("201.6.80.22");
assertEquals("201.6.80.22", a.toString());
a = new IPv4Address("123.5.117.95");
assertEquals("123.5.117.95", a.toString());
}
}
com.github.coderodde.util.net.IPFilterTest.java:
package com.github.coderodde.util.net;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public final class IPFilterTest {
@Test
public void test() {
IPFilter filter = new IPFilter();
assertTrue(filter.isEmpty());
assertEquals(0, filter.size());
filter.add("111.222.33.4");
assertFalse(filter.isEmpty());
assertEquals(1, filter.size());
assertTrue(filter.contains(new IPv4Address("111.222.33.4")));
assertTrue(filter.contains("111.222.33.4"));
assertFalse(filter.contains("111.222.33.5"));
filter.remove("111.222.33.4");
assertTrue(filter.isEmpty());
assertEquals(0, filter.size());
}
}
Critique request
Is there anything to improve? Tell me, please, anything.