【问题标题】:convert four 32 bits ints to IP address in java在java中将四个32位整数转换为IP地址
【发布时间】:2012-06-11 21:09:33
【问题描述】:

使用此处找到的代码:https://libbits.wordpress.com/2011/05/17/check-if-ip-is-within-range-specified-in-cidr-in-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 地址

【问题讨论】:

  • 也许在做这一切之前,你应该阅读二元运算符和内存模型。

标签: java ip type-conversion 32-bit


【解决方案1】:

这很容易。假设 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);

【讨论】:

    【解决方案2】:

    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 位以外的所有位输出 0。

    最后两个值也是如此。

    【讨论】:

      【解决方案3】:

      @Teetoo 答案的补充。

      让我们 ByteBuffer 做 int 到字节数组的魔法

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

      【讨论】:

      • 简单的位移逻辑的过度杀伤力:)
      • @Matt,哈哈,我喜欢简单。 (1) 它隐藏字节顺序的东西 (2) 它显示 C/C++ union {int, struct _addr{char,char,char,char} 在进行此类转换时的用法 (3) 代码更干净
      【解决方案4】:

      你可以使用

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

      扭转这种局面。

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

      【讨论】:

      • 这是在开玩笑吗?为什么要将常量向左移动 24 个字节然后向右移动 24 个字节? ;-)
      • 我认为您的意思是 24 位。 ;) 希望这能让它更清楚。
      猜你喜欢
      • 2012-10-26
      • 2014-10-07
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 2014-03-03
      相关资源
      最近更新 更多