今天终于搞懂了ip地址和整数之间的转换, 在这里和大家分享一下心得,唠叨一把。
事件起因:
项目中用到通过ip地址获取城市名称,这样的原码网上一搜一大把,基本上都是lumaQQ的东西,在这里夸赞一番,确
实不错。它的原码里面用到了ip和整数之间的转换,长途跋涉进行了研究(只因大学计算机基础没有学好,哎… 重新研
究二进制,八进制,16进制),皇天不负有心人啊,终于搞定了。
事件过程:
先得了解ip地址的“构造”是由32位二进制数组成的,然后再研究二进制的表示和Java的按位运算(在前面的博文中有
介绍),想了解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,结合前篇博文【传说中的Java基础东西(按位操作运算)】的&用法,你就很清楚为啥要&0x00FFFFFF了,它可以使前8为置为0,后16位是1或者0还是不变的。
然后就可以肆无忌惮的把ipLong表示的二进制数进行无符号的左移16位。
ipLong&0x00FFFFFF 可以得到00000000 00000000 00000011 11000001,然后让它>>>16位,
得到00000000 00000000 00000000 00000000,即为第二段的数字0、
依次类推、
最后一段直接把前24位都置为0,然后计算出来的整数即为最后一段的值了。

IP地址与长整数之间的转换详解相关推荐

  1. 计算机网络ip进制转换方法,IP地址与二进制之间的转换

    IP地址与二进制之间的转换 在讨论如何进行IP地址与二进制之间的转换前, 有必要解释一下IP地址与二进制的概念 IP IP协议是网络层的一个协议, 是能使连接到网上的所有计算机网络实现相互通信的一套规 ...

  2. IP地址与二进制之间的转换

    IP地址与二进制之间的转换 在讨论如何进行IP地址与二进制之间的转换前, 有必要解释一下IP地址与二进制的概念 IP IP协议是网络层的一个协议, 是能使连接到网上的所有计算机网络实现相互通信的一套规 ...

  3. C# IP地址和整数之间的转换,IP地址和数字ip地址的转换

    IP地址与整数之间的转换 1.IP地址转换为整数 原理:IP地址每段可以看成是8位无符号整数即0-255,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成一个无符号的32位整数. 举例:一 ...

  4. IP地址和域名之间的转换

    一.引言 域名,简单来理解就是我们平常说的网址.比如登录某度买假药时,会在IE浏览器的地址栏输入www.baidu.com,这里我们输入的就是百度的域名.而实际上我们在互联网中要找到某个网站,是需要这 ...

  5. java中IP地址与long之间的转换

    IP地址转为long型: public static long ipToLong(String ip) {String[] ipArray = ip.split("\\.");Li ...

  6. IP地址,子网掩码,网段 概念详解

    文章目录 1. 子网掩码 1.1 子网掩码的概念及作用 1.2 子网掩码的组成 1.3 子网掩码的表示方法 1.4 为什么要使用子网掩码? 1.5 子网掩码的分类 2. 子网掩码和IP地址的关系 2. ...

  7. [字符集]Unicode和UTF-8之间的转换详解

        最近在用VC++开发一个小工具,平时用惯了.NET,用起VC++最郁闷的就是字符串处理.当然最最让人难于琢磨的就是字符集,编码之间的转换.通过这几天的研究,终于明白了Unicode和UTF-8 ...

  8. Unicode和UTF-8之间的转换详解

    Unicode是一个字符集,而UTF-8是 Unicode的其中一种,Unicode是定长的都为双字节,而UTF-8是可变的,对于汉字来说Unicode占有的字节比UTF-8占用的字节少1 个字节.U ...

  9. java base64字符 转图片_JAVA实现图片与base64字符串之间的转换详解

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import ...

最新文章

  1. 从SAE又回到BAE,感觉好轻松
  2. python能解密java的,在python中解码Java对象
  3. python学到什么程度可以写爬虫-小白python学到什么程度可以学习网络爬虫? ?...
  4. 解决Ajax不能跨域的方法
  5. springboot启动自动关闭_App自动化测试用例格式和App的启动与关闭
  6. sigquit信号默认忽略吗_linux下的信号列表
  7. opencv7-绘制形状和文字
  8. 整合基因组学和蛋白质结构的致病机制分析
  9. 956. 最高的广告牌
  10. 安装cdr2019卡在正在下载_cdr2019最新版下载-coreldraw2019安装包中文版 - 极光下载站...
  11. Win10官方原版ISO下载
  12. Android MeasureSpec理解
  13. Abaqus齿轮有限元分析
  14. python 取整求余函数
  15. S3(Simple Storage Service) 对象存储 详细介绍
  16. Tableau 群集部署
  17. for循环打印等腰三角形
  18. 我的世界整合包内自带服务器,我的世界服务器整合包怎么用
  19. 【密码学Sage代码】椭圆曲线加密/解密(基于《密码编码学与网络安全——原理与实践(第七版)》)
  20. 学习AS400艰难的历程

热门文章

  1. 无法将“webpack”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
  2. ambari集群安装hdp
  3. 文件上传漏洞详解(CTF篇)
  4. wan口自动获取ip地址服务器无响应,电脑PPPoE拨号时WAN口获取不到IP地址,怎么办?...
  5. Jetson 关闭Gnome桌面
  6. Servlet 教程 各个知识点简单概括
  7. 遗传算法介绍三(来自维基百科)
  8. 【若依(ruoyi)】附件上传功能
  9. 广告公司客户关系管理教程
  10. HTTPS阮一峰博客总结