Java中将四个32位整数转换为IP地址

3
使用此处找到的代码:https://libbits.wordpress.com/2011/05/17/check-if-ip-is-within-range-specified-in-cidr-in-java/,可以检查IP是否在CIDR指定的范围内。
  // Step 1. Convert IPs into ints (32 bits). 
// E.g. 157.166.224.26 becomes 10011101  10100110  11100000 00011010
int addr = (( 157 << 24 ) & 0xFF000000) 
           | (( 166 << 16 ) & 0xFF0000) 
           | (( 224 << 8 ) & 0xFF00) 
           |  ( 26 & 0xFF);

// Step 2. Get CIDR mask
int mask = (-1) << (32 - 10);

// Step 3. Find lowest IP address
int lowest = addr & mask;

// Step 4. Find highest IP address
int highest = lowest + (~mask);

我能够将一个字符串分成四个整数,并为我的IP范围创建边界。现在我想生成一个介于最高值和最低值之间的IP地址。例如,给定范围:157.166.224.26/10,我得到一个地址为-1650008038,我的最低IP地址是-1652555776,最高IP地址是-1648361473。现在我需要生成一个介于最低和最高值之间的数字,并将其转换回四个整数,这最后一部分是我迷失的地方,我不确定如何将-1648361473转换为IP地址。

2
也许在做这一切之前,你应该先了解二进制运算符和内存模型。 - haylem
4个回答

5
很简单。假设IPv4地址在变量ipaddr中,您可以编写如下内容:
byte[] addr = new byte[4];
addr[0] = (ipaddr >> 24) & 0xFF;
addr[1] = (ipaddr >> 16) & 0xFF;
addr[2] = (ipaddr >> 8 ) & 0xFF;
addr[3] = ipaddr & 0xFF;

InetAddress inetAddr = InetAddress.getByAddress(addr);

1

您可以使用

int addr = (157 << 24) | (166 << 16) | (224 << 8) | 26;

要撤销这个操作。

byte[] addrAsBytes = { (byte) (addr >> 24), (byte) (addr >> 16), 
                (byte) (addr >> 8), (byte) addr };

这是个玩笑吗?你为什么要将一个常量左移24字节然后再右移24字节?;-) - user207421
我想你的意思是“24位”。希望这样更清楚了。 - Peter Lawrey

1
Teetoo上面提供的答案值得一些解释。
让我们从第一个值开始:
(ipaddr >> 24) & 0xFF

当这个数字向下移动时,表示157的8位数会在结果整数的最右边位置。然而,由于该值最初为负,你将在24位最高有效位上有1,这将导致你得到一个负数。你想要的是将所有但最后8位都清零,因此使用"& 0xFF"。另一种方法是使用">>>"运算符进行右移,该运算符强制将0插入到最高有效位中。

(ipaddr >>> 24)

现在我们继续:

(ipaddr >> 16) & 0xFF

当你进行移位操作时,因为移位负数将导致最左边的 16 位设置为 1。然后你将有代表 157 的 8 位和代表 166 的 8 位。在这种情况下,>>> 运算符对我们没有帮助,因为我们仍然有 157。因此,“& 0xFF”将会清除除了 166 的 8 位之外的所有位。

最后两个值的处理方式也是类似的。


1

对@Teetoo答案的补充。

ByteBuffer来完成int到byte数组的转换。

ByteBuffer bb = ByteBuffer.wrap (addr);
bb.putInt (iIP);

对于简单的位移逻辑来说,这有点过度了 :) - Matt
@Matt,哈哈,我喜欢它的简洁性。(1)它隐藏了字节顺序的东西。(2)当进行这种转换时,它展示了类似于C/C++ union {int, struct _addr{char,char,char,char} 的用法。(3)代码更干净。 - LiuYan 刘研

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接