IP地址与int或者long类型互转(Java、PHP)
来源:互联网 发布:重庆数据分析的项目 编辑:程序博客网 时间:2024/06/06 11:37
对数据库了解的同学都知道数字类型其实是要比字符串类型的column在处理上速度快很多的,所以为了存储和查询速度考虑,我们通常把IP地址转为数字来存储,通常用int存储,但是要注意要使用
unsigned
,不然128以上的就无法存储了。
原理
那我们究竟如何存储IP地址呢?
- 我们知道IP地址(ipv4)分为四段,每一段的范围是0-255,而这个范围恰好可以用8bit的二进制来表示,因为2的8次方为256,从0到255正好为256个数字。
- 所以,实际上我们可以用类似
xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
的形式来表示一个ipv4的地址,其中x
为0或1。 - 然后,我们把中间的点去掉,就是一个32bit的二进制数字了,恰好是一个int类型(数据库中占32bit)所能表示的范围。
- 因此,我们只需要将IP每一段都用二进制表示,再拼到一起,就可以表示一个IP地址了。
如何拼装
- 以
10.1.8.12
为例,四段分别是10
、1
、8
、12
,用8bit的二进制表示分别为00001010
、00000001
、00001000
、00001100
,其中不足8位的数字用0在左边补齐。 - 最后我们要的结果其实是
00001010000000010000100000001100
,也就是按照顺序,拼接起来,转为十进制位167839756
(我口算的,你们信不;-))。 - 我们依次从左到右这四段,分别左移24位、16位、8位、0位,Java中位用逻辑左移运算符
<<
,然后我们可以得到00001010000000000000000000000000
,000000010000000000000000
,0000110000000000
,00001100
。 - 最后我们将这几段二进制数做或操作,Java中逻辑或运算符为
|
(有一个为1则此位为1)于是我们就可以得到00001010000000010000100000001100
, 十进制就是167839756.
如何还原
- 明白了如何拼装的之后,我们还原就很容易了
- 我们把这个长长的数字右移,分别把
00001010000000010000100000001100
右移24位、16位、8位、0位,然后得到00001010
、0000101000000001
、000010100000000100001000
、00001010000000010000100000001100
- 然后,我们用
11111111
也就是0xFF
来跟上述的四段数字以此做与操作,java中运算符位&
(同1为1,有一个为0则此位为0), 我们就可以得到00001010
、00000001
、00001000
、00001100
,十进制依次为:10
、1
、8
、12
,最后中间加点,就还原了。 - 这个与操作实际上就是起到了截断的作用,只取8位,因为
0xFF
只有8位,其左边可以用任意多的0填充,例如0xFF
跟 例子IP中的第三段做与操作:000000000000000011111111 & 000010100000000100001000
,根据与运算的规则,高于8位的都是跟0与,所以得到的也全是0,真正有效的低8位。 - 事实上,开头的
10
,我们完全可以不用与操作,因为右移24位后,就剩下8位,就是我们要的。
代码实现
Java
package com.vien.ip;/** * @author Vien * @date 2017/11/17 */public class IPUtils { /** * convert ip to long * * @param ip the string of ip address * @return long of ip */ public static long ip2long(String ip) { System.out.println(ip); String[] slice = ip.split("\\."); return (Long.valueOf(slice[0]) << 24) | (Long.valueOf(slice[1]) << 16) | (Long.valueOf(slice[2]) << 8) | Long.valueOf(slice[3]); } /** * convert long to ip * * @param ip long * @return string of ip */ public static String long2ip(long ip) { StringBuilder ipStr = new StringBuilder(); ipStr.append((ip >>> 24)).append("."); ipStr.append((ip >>> 16) & 0xFF).append("."); ipStr.append((ip >>> 8) & 0xFF).append("."); ipStr.append(ip & 0xFF); return ipStr.toString(); } public static void main(String[] args) { System.out.println(ip2long("10.1.8.12")); System.out.println(long2ip(167839756)); }}
PHP
其实PHP提供了相关函数ip2long() 将 IP转为longlong2ip() 将 long还原为IP
MySQL
MySQL也提供相关函数,可以用于查询,例如:mysql> select inet_aton('10.1.8.12');+------------------------+| inet_aton('10.1.8.12') |+------------------------+| 167839756 |+------------------------+1 row in set (0.01 sec)mysql> select inet_ntoa(167839756);+----------------------+| inet_ntoa(167839756) |+----------------------+| 10.1.8.12 |+----------------------+1 row in set (0.00 sec)
更多:vien.我爱你
阅读全文
0 0
- IP地址与int或者long类型互转(Java、PHP)
- ip地址与int类型的转换
- ip地址与int类型的转换
- java十进制数字转十六进制(int类型太大无法转换,把int类型转为Long类型计算)
- Java:int 转 long
- Java-int与string类型互转
- ip转数字,ip地址转十进制 long类型,ip转十进制输出负数
- int ,long , long long类型的范围(转)
- java long转换为int 类型 注意事项
- java运算类型转化int long
- java long转换为int 类型 注意事项
- long long 与 int(HDOJ 2294)
- int 与 long 、long long
- Java 字节数组类型(byte[])与int类型互转
- JAVA IP地址与数字互转
- Java:ip与long互转
- int,long类型范围
- int ,long , long long类型的范围
- MySQL分页查询优化
- TensorRT Samples: MNIST API
- 如何捕获微信自带的返回键监听
- oracle 查询前一行或后一行数据
- 浅谈微信小程序前端生态
- IP地址与int或者long类型互转(Java、PHP)
- Redis和请求队列解决高并发
- servlet02_servlet的三个hashMap
- Sql Server 捕获异常信息
- Java 编程:如何提高性能?(简单总结篇)
- stack around variable ## was corrupted问题
- Tablayout左右滑动和Banner无限轮播的配合使用
- java ArryList 转 String (借助commons-lang.jar)
- docker中安装Nexus3