对数据库了解的同学都知道数字类型其实是要比字符串类型的column在处理上速度快很多的,所以为了存储和查询速度考虑,我们通常把IP地址转为数字来存储,通常用int存储,但是要注意要使用
unsigned
,不然128以上的就无法存储了。
xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
的形式来表示一个ipv4的地址,其中x
为0或1。10.1.8.12
为例,四段分别是10
、 1
、 8
、 12
,用8bit的二进制表示分别为00001010
、00000001
、00001000
、00001100
,其中不足8位的数字用0在左边补齐。00001010000000010000100000001100
,也就是按照顺序,拼接起来,转为十进制位167839756
(我口算的,你们信不;-))。<<
,然后我们可以得到00001010000000000000000000000000
,000000010000000000000000
, 0000110000000000
, 00001100
。|
(有一个为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
,最后中间加点,就还原了。0xFF
只有8位,其左边可以用任意多的0填充,例如0xFF
跟 例子IP中的第三段做与操作:000000000000000011111111 & 000010100000000100001000
,根据与运算的规则,高于8位的都是跟0与,所以得到的也全是0,真正有效的低8位。10
,我们完全可以不用与操作,因为右移24位后,就剩下8位,就是我们要的。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提供了相关函数
ip2long() 将 IP转为long
long2ip() 将 long还原为IP
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.我爱你
viencoding.com版权所有,允许转载,但转载请注明出处和原文链接: https://viencoding.com/article/34