这段Java代码如何将IP地址转换?

3
在下面的示例代码中,能否对以下行进行更详细的解释,就像你向初学者解释一样。
for (byte octet : octets) {
        result <<= 8;
        result |= octet & 0xff;
    }



public class Example {
public static long ipToLong(InetAddress ip) {
    byte[] octets = ip.getAddress();
    long result = 0;
    for (byte octet : octets) {
        result <<= 8;
        result |= octet & 0xff;
    }
    return result;
}

public static void main(String[] args) throws UnknownHostException {
    long ipLo = ipToLong(InetAddress.getByName("192.200.0.0"));
    long ipHi = ipToLong(InetAddress.getByName("192.255.0.0"));
    long ipToTest = ipToLong(InetAddress.getByName("192.200.3.0"));

    System.out.println(ipToTest >= ipLo && ipToTest <= ipHi);
}

}


1
new BigInteger(ip.getAddress()).longValue()替换。 - jtahlborn
1个回答

2
  • byte[] octets = ip.getAddress(); -> 将整个IP地址存储为字节数组

  • for (byte octet : octets) {} -> 将字节数组拆分为八位字节并迭代它们

  • result <<= 8 (shorthand for result = result<<8) -> 左移8位 将结果向左二进制移动8位,并添加8个尾部零。 (通过2的8次幂将结果的值乘以2 ^ 8)

  • result |= octet & 0xff; (same as result|=octet which is shorthand for result = result | or octect -> 按位或,在这种情况下相当于加法,因为在上一步之后,结果末尾有8个零。

编辑(感谢@jtahlborn)->与0xFF进行按位与运算是必要的,以避免在将字节转换为int时发生符号扩展。

示例

问题IP地址为192.200.3.0。最终值是在以下方式生成的:

192*(2^24) + 200*(2^16) + 3*(2^8) + 0*(2^0)
3221225472 + 13107200 + 768 = 3234333440

现在你的代码使用位移运算来完成相同的任务。 192的二进制是11000000。首先,它被加到结果中result = 0;现在result是11000000。 然后它被左移8位(相当于乘以2 ^ 8),结果是11000000 00000000
现在,添加二进制值200,即11001000,使得结果变为11000000 11001000。 这个过程一直持续下去,直到您拥有以下32位数字:11000000 11001000 00000011 00000000,它可以转换为相同的3234333440。

2
0xFF是必要的,以避免在将字节转换为整数时发生符号扩展。 - jtahlborn
我忘了那个!太棒了! - Anirudh Ramanathan
@jtahlborn 不错!我甚至没有想到那个。 - Rob Wagner
谢谢,写得很好,我会接受这个答案...但是它为什么会这样做呢?“左移8位将二进制结果向左移动8位,并添加8个尾随零。(将结果的值乘以2^8)”,你能再解释一下吗?谢谢! - James

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