利用位操作进行IP地址的转化

1)IPv4地址是一个32位的二进制数,通常被分割位4个“8位二进制数”,为了方便,通常使用“点分十进制”的形式表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数,另外,IP地址也可以使用一个3的整数T表示,根据点分十进制中的a,b,c,d,计算T的方法就是:

T=a*256*256*256+b*256*256+c*256+d;

2)那么如何根据T反求出此IP地址的“点分十进制”形式呢?题目描述:

IP地址的长度为32,即有2^32-1个地址。IP地址一般采用点分十进制表示法,例如"192.168.1.1"。IP地址也可以直接用一个32位的整数进行表示。本题目要求根据给定的整数IP地址表示发,将其转换为点分十进制的形式。
举个例子:
      输入整数IP地址为 3232235777
      其对应十六进制为 0xC0A80101
      每字节转为十进制 0xC0=192,0xA8=168,0x01=1,0x01=1
      则输出为 192.168.1.1

 

有两种方法可以采用,我们首先谈谈怎么使用“位操作”解决这个问题。IP地址实质上是一个32位的二进制形式,虽然说T是一个整数,不过其在计算机存储形式仍然是二进制的形式,使用“位操作”可以方便的得到IP地址中四个网段(也就是4个“8位二进制数”),代码如下:

public static String bitOperation(){
    Long ipAddrLong=0l;
    Scanner scanner=new Scanner(System.in);
    if (scanner.hasNextLong()) {
        ipAddrLong=scanner.nextLong();
    }
    long test;
    StringBuilder sb=new StringBuilder();
    for (int i = 0; i <4; i++) {
        test=(ipAddrLong&0xff);//当与操作的两个操作数位数不一致时,在较少位的操作数左侧补0,直至位数相等
        sb.insert(0, Long.toString(test));//StringBuild的insert()方法很好用
        //sb.append(Long.toString(test));
        if (i<3) {
            sb.insert(0, ".");
        }
        ipAddrLong=ipAddrLong>>8;//无论是左移还是右移,操作数都是在“>>”或者"<<"的左侧,右侧是要改变的位数,并且移动之后,
        //并不改变原操作数的内容,而是新创造了一个数值。左移是将操作数的二进制码整体移动指定位数,所以要操作数最右侧的若干位会丢失,为了保证从操作数
        //的位数不变,在最左侧补上与移动次数相同个数的0。
    }
    return sb.toString();
}

与左移不同的是,右移运算符有两个:“>>”和“>>>”。对于“>>”而言,把操作数的整体二进制码右移指定位之后,左侧空出来的部分使用操作数原来的符号位代替。而“>>>”是无符号右移操作符,左侧空出来的部分总是使用0代替。

参考:http://www.what21.com/programming/java/java-algorithm/ip.html

3)还有另外一种方法可以将IP地址的正数形式转化为“点分十进制”的形式,主要就是取模和取余,代码如下:

1 private static String getIP(Long ipaddr) { 
2     long y = ipaddr % 256; 
3     long m = (ipaddr - y) / (256 * 256 * 256); 
4     long n = (ipaddr - 256 * 256 *256 * m - y) / (256 * 256); 
5     long x = (ipaddr - 256 * 256 *256 * m - 256 * 256 *n - y) / 256; 
6     return m + "." + n + "." + x + "." + y; 
7 } 

参考:http://blog.csdn.net/shb_derek1/article/details/8064308

posted @ 2016-03-28 17:24  lz3018  阅读(1221)  评论(0编辑  收藏  举报