IP地址与长整数之间的转换详解

1、Ip转换为长整数的代码:

public static long ipToLong(String ipString){  
      long result = 0;  
      java.util.StringTokenizer token = new java.util.StringTokenizer(ipString,".");  
      result += Long.parseLong(token.nextToken())<<24;  
      result += Long.parseLong(token.nextToken())<<16;  
      result += Long.parseLong(token.nextToken())<<8;  
      result += Long.parseLong(token.nextToken());  
      return result;  
  }  

原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
 
举例:一个ip地址为10.0.3.193
每段数字             相对应的二进制数
10                   00001010
0                    00000000
3                    00000011
193                  11000001
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。


在上面的方法中,原理都是一样的。我用到了位移操作,因为它就是操作的二进制数,使用位移操作很方面、直观。
Long.parseLong(token.nextToken())<<24 就是把第一段数字表示的二进制数左移了24位,(记住:按位操作符都操作的整数的二进制数)

得到00001010 00000000 00000000 00000000;
依次类推:
Long.parseLong(token.nextToken())<<16,得到00000000 00000000 00000000 00000000;
Long.parseLong(token.nextToken())<<8,得到00000000 00000000 00000011 00000000;
Long.parseLong(token.nextToken()),最低位不用移动,得到00000000 00000000 00000000 11000001;
把这四个二进制数转换为整数后相加和00001010 00000000 00000011 11000001表示的二进制数是一样的(这个就不多说了,明白人一看就知道了)。


2、长整数转换为Ip的代码:

public static String longToIp(long ipLong){  
      StringBuilder sb = new StringBuilder();  
      sb.append(ipLong>>>24);sb.append(".");  
      sb.append(String.valueOf((ipLong&0x00FFFFFF)>>>16));sb.append(".");  
      sb.append(String.valueOf((ipLong&0x0000FFFF)>>>8));sb.append(".");  
      sb.append(String.valueOf(ipLong&0x000000FF));  
      return sb.toString();  
  }  

原理:很简单的,就是$1的“反编码”(就这样先叫着),先把这个长整数转换成一个32位的二进制数。从左到右,每8位
进行一下分割,就得到4段8位的二进制数,把这些二进制数转换成整数然后加上”.”就是这个ip地址了。
 
举例:167773121
二进制表示形式为:00001010 00000000 00000011 11000001
分割成四段:00001010,00001010,00000011,11000001,分别转换为整数后加上“.”就得到了10.0.3.193。
每段怎么计算为整数的呢,比如00001010,一个整数是32位的整数,所以前面全部补0(也就是说把该段的8位看成是低位数字,高位全部补0,

得到一个32位的二进制数,即为一个整数的二进制数表示形式),由此可以得到
00000000 00000000 00000000 00001010,就是传说中的10,其他三个数字也就相继可以得到了。
上面的longToIp方法使用也是与$1中位移操作正好相反。
先得到第一段(它是二进制数的左边)的整数,那个长整型的二进制数字无符号左移24位(正好是前面都补0),得到一个二
进制数即为最高位的数字。即可以用位移实现ipLong>>>24(>>>操作的是ipLong的二进制数);
想得到第二段,就要把ipLong表示的二进制数进行无符号左移16位,但是它的左边不一定为0(还有第一段数字的二进制数
呢),所以在移位之前先把前面的的8位置为0,就可以用ipLong&0x00FFFFFF表示。
0x00FFFFFF是什么呢?为什么要&0x00FFFFFF呢?

0x00FFFFFF是一个16进制数,它的二进制表示形式为00000000 11111111 11111111 11111111,它可以使前8为置为0,后16位是1或者0还是不变的。 
然后就可以肆无忌惮的把ipLong表示的二进制数进行无符号的左移16位。
ipLong&0x00FFFFFF 可以得到00000000 00000000 00000011 11000001,然后让它>>>16位,
得到00000000 00000000 00000000 00000000,即为第二段的数字0、
依次类推、最后一段直接把前24位都置为0,然后计算出来的整数即为最后一段的值了。

Leave a Reply