IPv4可以有更多的表示形式:字符串(a.b.c.d)或数字(32位的无符号整数)。(也许是其他的,但我会忽略它们。
Java (8) 中是否有任何内置支持,简单易用,无需网络访问,可以在这些格式之间进行转换?
我需要这样的东西:
long ip = toNumerical("1.2.3.4"); // returns 0x0000000001020304L
String ipv4 = toIPv4(0x0000000001020304L); // returns "1.2.3.4"
如果 Java 中没有内置此类函数,请随时提出其他解决方案。
谢谢
可以使用InetAddress
完成,如下所示。
//Converts a String that represents an IP to an int.
InetAddress i = InetAddress.getByName(IPString);
int intRepresentation = ByteBuffer.wrap(i.getAddress()).getInt();
//This converts an int representation of ip back to String
i = InetAddress.getByName(String.valueOf(intRepresentation));
String ip = i.getHostAddress();
这是一种将 IP 转换为数字的方法。我发现这是在 Java 中完成任务的有效方法。
public long ipToLong(String ipAddress) {
String[] ipAddressInArray = ipAddress.split("\.");
long result = 0;
for (int i = 0; i < ipAddressInArray.length; i++) {
int power = 3 - i;
int ip = Integer.parseInt(ipAddressInArray[i]);
result += ip * Math.pow(256, power);
}
return result;
}
这也是你在 Scala 中实现它的方式。
def convertIPToLong(ipAddress: String): Long = {
val ipAddressInArray = ipAddress.split("\.")
var result = 0L
for (i <- 0 to ipAddressInArray.length-1) {
val power = 3 - i
val ip = ipAddressInArray(i).toInt
val longIP = (ip * Math.pow(256, power)).toLong
result = result +longIP
}
result
}
QuakeCore 提供的代码片段会在您要将其转换回字符串的部分抛出"java.net.UnknownHostException: 无法解析主机"
但是使用 InetAddress 类的想法是正确的。以下是您要执行的操作:
try {
InetAddress inetAddressOrigin = InetAddress.getByName("78.83.228.120");
int intRepresentation = ByteBuffer.wrap(inetAddressOrigin.getAddress()).getInt(); //1314120824
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.putInt(intRepresentation);
byte[] b = buffer.array();
InetAddress inetAddressRestored = InetAddress.getByAddress(b);
String ip = inetAddressRestored.getHostAddress();//78.83.228.120
} catch (UnknownHostException e) {
e.printStackTrace(); //
}
PS:如果您要对某些 ip 列表执行此操作,请验证它们以确保它们没有子网掩码,例如:78.83.228.0/8
在这种情况下,您需要展平它们:78.83.228.0/8
=>
78.83.228.0
78.83.228.1
78.83.228.2
78.83.228.3
78.83.228.4
78.83.228.5
78.83.228.6
78.83.228.7
我建议:
long ip2long() {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.BIG_ENDIAN);
buffer.put(new byte[] { 0,0,0,0 });
buffer.put(socket.getInetAddress().getAddress());
buffer.position(0);
return buffer.getLong();
}