ipv4可转成long已经由来已久,对于ipv6因为需要用两个long的大小存储所以转成了BigInteger,数据库中ipv6存成binary类型,可以用between 方式实现范围查询,
因ipv4转成的long也可调用ipv6的转v6方法,所以为避免v4与v6存储冲突,ipv6存储时建议在转为的数值加上ipv4的最大值(255.255.255.255见示例中的maxIPv4Number),当然在转回ipv6字符前,需要再减去这个ipv4最大值,
这样可以在执行范围查询时避免ipv6规则查出ipv4的记录
public class IPTransfer {
public static BigInteger maxIPv4Number = BigInteger.valueOf(4294967295L);//255.255.255.255
private static final long PART1 = 0xff000000;
private static final long PART2 = 0xff0000;
private static final long PART3 = 0xff00;
private static final long PART4 = 0xff;
/** 将IP地址长整型数值转化为IPv4字符串 */
public static String longToIPv4(long ip) {
String ipStr = String.valueOf((ip & PART1) >> 24);
ipStr += "." + ((ip & PART2) >> 16);
ipStr += "." + ((ip & PART3) >> 8);
ipStr += "." + (ip & PART4);
return ipStr;
}
/** 将IPv4字符串转化为对应的长整型整数 */
public static long ipv4ToLong(String ipv4) {
String[] p4 = ipv4.split("\\.");
long ipInt = 0;
long part = Long.valueOf(p4[0]);
ipInt = ipInt | (part << 24);
part = Long.valueOf(p4[1]);
ipInt = ipInt | (part << 16);
part = Long.valueOf(p4[2]);
ipInt = ipInt | (part << 8);
part = Long.valueOf(p4[3]);
ipInt = ipInt | (part);
return ipInt;
}
public static BigInteger ipv6ToNumber(String addr) {
try {
InetAddress ia = InetAddress.getByName(addr);
byte byteArr[] = ia.getAddress();
return new BigInteger(1, byteArr);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
public static String numberToIPv6(BigInteger ipNumber) {
String ipString ="";
BigInteger a=new BigInteger("FFFF", 16);
for (int i=0; i<8; i++) {
ipString=ipNumber.and(a).toString(16)+":"+ipString;
ipNumber = ipNumber.shiftRight(16);
}
return ipString.substring(0, ipString.length()-1);
}
}