利用位操作进行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 }