Java:将int转换为InetAddress
我有一个Java:将int转换为InetAddress,java,inetaddress,Java,Inetaddress,我有一个int,其中包含一个按网络字节顺序排列的IP地址,我想将其转换为InetAddress对象。我看到有一个InetAddress构造函数接受字节[],是否需要先将int转换为字节[],还是有其他方法?这应该可以: int ipAddress = .... byte[] bytes = BigInteger.valueOf(ipAddress).toByteArray(); InetAddress address = InetAddress.getByAddress(bytes); 您可能
int
,其中包含一个按网络字节顺序排列的IP地址,我想将其转换为InetAddress
对象。我看到有一个InetAddress
构造函数接受字节[]
,是否需要先将int
转换为字节[]
,还是有其他方法?这应该可以:
int ipAddress = ....
byte[] bytes = BigInteger.valueOf(ipAddress).toByteArray();
InetAddress address = InetAddress.getByAddress(bytes);
您可能必须交换字节数组的顺序,我无法确定数组是否以正确的顺序生成。这可能会起作用,请尝试
public static String intToIp(int i) {
return ((i >> 24 ) & 0xFF) + "." +
((i >> 16 ) & 0xFF) + "." +
((i >> 8 ) & 0xFF) + "." +
( i & 0xFF);
}
没有足够的声誉来评论斯卡夫曼的回答,所以我将补充这一点作为一个单独的答案 斯卡夫曼提出的解决方案是正确的,只有一个例外。toByteArray()返回一个可能有前导符号位的字节数组
byte[] bytes = bigInteger.toByteArray();
byte[] inetAddressBytes;
// Should be 4 (IPv4) or 16 (IPv6) bytes long
if (bytes.length == 5 || bytes.length == 17) {
// Remove byte with most significant bit.
inetAddressBytes = ArrayUtils.remove(bytes, 0);
} else {
inetAddressBytes = bytes;
}
InetAddress address = InetAddress.getByAddress(inetAddressBytes);
PS上面的代码使用Apache Commons Lang中的ArrayUtils。我认为这段代码更简单:
static public byte[] toIPByteArray(int addr){
return new byte[]{(byte)addr,(byte)(addr>>>8),(byte)(addr>>>16),(byte)(addr>>>24)};
}
static public InetAddress toInetAddress(int addr){
try {
return InetAddress.getByAddress(toIPByteArray(addr));
} catch (UnknownHostException e) {
//should never happen
return null;
}
}
测试和工作:
int ip = ... ;
String ipStr =
String.format("%d.%d.%d.%d",
(ip & 0xff),
(ip >> 8 & 0xff),
(ip >> 16 & 0xff),
(ip >> 24 & 0xff));
使用谷歌番石榴:
字节[]字节=整数toByteArray(ipAddress)
InetAddress=InetAddress.getByAddress(字节) 如果您使用的是谷歌的Guava库,
InetAddresses.fromInteger
正是您想要的。Api文档是
如果您想编写自己的转换函数,可以按照@aalmeida的建议进行操作,但要确保字节的顺序正确(最重要的字节排在第一位)
您可以使用此函数将int转换为字节 由于评论无法格式化,让我通过@Mr.KevinThomas发布来自评论的代码:
if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
ipAddress = Integer.reverseBytes(ipAddress);
}
sReturn = String.format(Locale.US, "%d.%d.%d.%d", (ipAddress >> 24 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 8 & 0xff), (ipAddress & 0xff));
它已经在Android上进行了测试。你能举个例子说明这个int的样子以及它的字符串表示形式应该是什么样子吗?我无法想象如何将255255放在一个整数中,它会溢出。@BalusC:IPv4地址只是一个32位的数字,只是它通常表示为4个8位的值。不过,这些信息正好适合32位。请记住,如果你想支持IPv6,就不能使用单个int来处理IP地址。他要求int到bytearray,而不是int到string。你说的“这可能有用,试试看”让我觉得你只是在谷歌上搜索了盲目复制的随机函数?为什么?这确实仍然需要交换字节数组的顺序。然而,事实证明,我的输入毕竟是按照主机顺序进行的!谢谢。对于0.0.0.0-0.127.255.255和255.128.0.0-255.255.255范围内的地址不起作用:
字节数将少于4elements@NikolayKuznetsov因为这些范围将导致字节数组大小为3或更小,而InetAddress要求数组大小为4或16.0。不起作用,例如对于0.0.0.0。不可靠!我不认为额外的前导符号位会有问题,但是如果地址在0.0.0.0-0.127.255.255和255.128.0.0-255.255.255之间,就会丢失字节。对不起,我不是这方面的专家。你能详细谈谈你的评论吗?恐怕我没有抓住要点(而且我的代码中可能有一个bug;)。@DennisLaumen,是的。例如,尝试0、42或-42。您应该得到0.0.0.0、0.0.0.42和255.255.255.214。相反,你会得到一个例外。请看,这几乎是正确的,但是您将字节的顺序向后:您的答案中的链接是broken@redbeam_已更新。这将以错误的顺序转换字节。它适用于小端整数,但问题是关于“网络字节顺序”的,它和Java中的整数一样是大端整数。正确的顺序是:String.format(“%d.%d.%d.%d”,(ip>>24&0xff),(ip>>16&0xff),(ip>>8&0xff),(ip&0xff))代码>
public static byte[] int32toBytes(int hex) {
byte[] b = new byte[4];
b[0] = (byte) ((hex & 0xFF000000) >> 24);
b[1] = (byte) ((hex & 0x00FF0000) >> 16);
b[2] = (byte) ((hex & 0x0000FF00) >> 8);
b[3] = (byte) (hex & 0x000000FF);
return b;
}
if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
ipAddress = Integer.reverseBytes(ipAddress);
}
sReturn = String.format(Locale.US, "%d.%d.%d.%d", (ipAddress >> 24 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 8 & 0xff), (ipAddress & 0xff));