ip util functions and its unit test
This commit is contained in:
parent
83fd149c59
commit
697b46bb2e
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.lionsoul.ip2region.xdb;
|
||||||
|
|
||||||
|
public class InvalidInetAddressException extends Exception {
|
||||||
|
|
||||||
|
public InvalidInetAddressException(String str) {
|
||||||
|
super(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,18 +7,61 @@
|
||||||
|
|
||||||
package org.lionsoul.ip2region.xdb;
|
package org.lionsoul.ip2region.xdb;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
public class Util
|
public class Util
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// parse the specified IP address and return its bytes.
|
||||||
|
// returns: byte[4] for IPv6 and byte[16] for IPv6 and the bytes should be in Big endian order.
|
||||||
|
public static byte[] parseIP(String ip) throws InvalidInetAddressException {
|
||||||
|
try {
|
||||||
|
return InetAddress.getByName(ip).getAddress();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw new InvalidInetAddressException("invalid ip address `"+ip+"`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the ip in bytes
|
||||||
|
public static String ipToString(final byte[] ip) throws InvalidInetAddressException {
|
||||||
|
if (ip.length != 4 && ip.length != 16) {
|
||||||
|
throw new InvalidInetAddressException("invalid ip address length `"+ip.length+"`");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return InetAddress.getByAddress(ip).getHostAddress();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw new InvalidInetAddressException("invalid ip address `"+ipArrayString(ip)+"`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// implode the byte[] ip with its byte value.
|
||||||
|
public static String ipArrayString(byte[] ip) {
|
||||||
|
final StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append("[");
|
||||||
|
for (int i = 0; i < ip.length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sb.append(',');
|
||||||
|
}
|
||||||
|
sb.append((ip[i] & 0xFF));
|
||||||
|
}
|
||||||
|
sb.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// compare two byte ip
|
// compare two byte ip
|
||||||
// Returns: -1 if ip1 < ip2, 0 if ip1 == ip2, 1 if ip1 > ip2
|
// Returns: -1 if ip1 < ip2, 0 if ip1 == ip2, 1 if ip1 > ip2
|
||||||
public static int ipCompare(byte[] ip1, byte[] ip2) {
|
public static int ipCompare(byte[] ip1, byte[] ip2) {
|
||||||
for (int i = 0; i < ip1.length; i++) {
|
for (int i = 0; i < ip1.length; i++) {
|
||||||
if (ip1[i] < ip2[i]) {
|
// covert the byte to int to sure the uint8 attribute
|
||||||
|
final int i1 = (int)(ip1[i] & 0xFF);
|
||||||
|
final int i2 = (int)(ip2[i] & 0xFF);
|
||||||
|
if (i1 < i2) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip1[i] > ip2[i]) {
|
if (i1 > i2) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,10 +73,13 @@ public class Util
|
||||||
final byte[] r = new byte[ip.length];
|
final byte[] r = new byte[ip.length];
|
||||||
System.arraycopy(ip, 0, r, 0, ip.length);
|
System.arraycopy(ip, 0, r, 0, ip.length);
|
||||||
for (int i = ip.length - 1; i >= 0; i--) {
|
for (int i = ip.length - 1; i >= 0; i--) {
|
||||||
|
final int v = (int)(r[i] & 0xFF);
|
||||||
|
if (v < 255) { // No overflow
|
||||||
r[i]++;
|
r[i]++;
|
||||||
if (r[i] != 0) { // No overflow
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -43,10 +89,12 @@ public class Util
|
||||||
final byte[] r = new byte[ip.length];
|
final byte[] r = new byte[ip.length];
|
||||||
System.arraycopy(ip, 0, r, 0, ip.length);
|
System.arraycopy(ip, 0, r, 0, ip.length);
|
||||||
for (int i = ip.length - 1; i >= 0; i--) {
|
for (int i = ip.length - 1; i >= 0; i--) {
|
||||||
if (r[i] != 0) { // No borrow needed
|
final int v = (int)(r[i] & 0xFF);
|
||||||
|
if (v > 0) { // No borrow needed
|
||||||
r[i]--;
|
r[i]--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r[i] = (byte) 0xFF; // borrow from the next byte
|
r[i] = (byte) 0xFF; // borrow from the next byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
package org.lionsoul.ip2region.xdb;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class UtilTest {
|
||||||
|
|
||||||
|
public static final Log log = Log.getLogger(UtilTest.class).setLevel(Log.DEBUG);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCheckIP() throws InvalidInetAddressException {
|
||||||
|
final String[] ips = new String[]{
|
||||||
|
"192.168.1.102",
|
||||||
|
"219.133.111.87",
|
||||||
|
"::",
|
||||||
|
"3000::",
|
||||||
|
"::1001:ffff",
|
||||||
|
"2001:2:0:ffff:ffff:ffff:ffff:ffff",
|
||||||
|
"::ffff:114.114.114.114"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String ip : ips) {
|
||||||
|
final byte[] ipBytes = Util.parseIP(ip);
|
||||||
|
log.debugf("%s(v=%s) => %s", ip, Util.ipArrayString(ipBytes), Util.ipToString(ipBytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIpCompare() throws InvalidInetAddressException {
|
||||||
|
final String[][] ipPairs = new String[][]{
|
||||||
|
{"1.0.0.0", "1.0.0.1"},
|
||||||
|
{"192.168.1.101", "192.168.1.90"},
|
||||||
|
{"219.133.111.87", "114.114.114.114"},
|
||||||
|
{"2000::", "2000:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
|
||||||
|
{"2001:4:112::", "2001:4:112:ffff:ffff:ffff:ffff:ffff"},
|
||||||
|
{"ffff::", "2001:4:ffff:ffff:ffff:ffff:ffff:ffff"}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String[] ips : ipPairs) {
|
||||||
|
final byte[] ip1 = Util.parseIP(ips[0]);
|
||||||
|
final byte[] ip2 = Util.parseIP(ips[1]);
|
||||||
|
log.debugf("compare(%s, %s): %d", ips[0], ips[1], Util.ipCompare(ip1, ip2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIpAddOne() throws InvalidInetAddressException {
|
||||||
|
final String[] ips = new String[] {
|
||||||
|
"1.0.0.0",
|
||||||
|
"192.168.1.255",
|
||||||
|
"2000::",
|
||||||
|
"255.255.255.254",
|
||||||
|
"0.0.0.255",
|
||||||
|
"0.255.255.255",
|
||||||
|
"1.1.255.255"
|
||||||
|
};
|
||||||
|
for (String ip : ips) {
|
||||||
|
final byte[] ipBytes = Util.parseIP(ip);
|
||||||
|
log.debugf("ipAddOne(%s): %s", ip, Util.ipToString(Util.ipAddOne(ipBytes)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIpSubOne() throws InvalidInetAddressException {
|
||||||
|
final String[] ips = new String[] {
|
||||||
|
"192.168.1.255",
|
||||||
|
"1.0.0.1",
|
||||||
|
"1.0.0.0",
|
||||||
|
"2.0.0.0",
|
||||||
|
"2000::",
|
||||||
|
"ffff::",
|
||||||
|
"1::1",
|
||||||
|
};
|
||||||
|
for (String ip : ips) {
|
||||||
|
final byte[] ipBytes = Util.parseIP(ip);
|
||||||
|
log.debugf("ipSubOne(%s): %s", ip, Util.ipToString(Util.ipSubOne(ipBytes)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue