2012-06-07 49 views
3

使用这里找到代码:https://libbits.wordpress.com/2011/05/17/check-if-ip-is-within-range-specified-in-cidr-in-java/转换4个32位整型到IP地址在java中

// 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

回答

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 }; 
+0

这是个玩笑吗?为什么要将常量左移24个字节然后右移24个字节? ;-) – EJP

+0

我认为你的意思是* 24位。*;)希望这可以让它更清晰。 –

1

Teetoo以上做出的答案值得一些解释。

让我们开始与所述第一值:

(ipaddr >> 24) & 0xFF 

当此向下移位,代表157的8位是在所得到的整数的最右边的位置。然而,由于这个值最初是负值,所以你会在24个最高有效位中有1,这最终会给你一个负数。你想要的是除了最后8位之外的全部0,因此“& 0xFF”。另一种方法是使用>>>操作符向右移位,该操作符将0强制为最高有效位。

(ipaddr >>> 24) 

现在我们进入到:

(ipaddr >> 16) & 0xFF 

当你移动,你必须设置为1,16最左边的位(由于移负数)。然后你将有8位代表157,然后8位代表166。在这种情况下,>>>运算符不会帮助我们,因为我们仍然有157位。所以“& 0xFF”将除0的16位外全部为8位。

类似地对于最后两个值。

1

除了@ Teetoo的回答。

咱们ByteBuffer做的int字节数组魔法

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

矫枉过正简单的移位逻辑:) – Matt

+0

@Matt,哈哈,我喜欢简单。 (1)它隐藏了字节顺序的东西(2)它显示了C/C++'union {int,struct _addr {char,char,char,char}'这样的转换时的用法(3)代码更清晰 –