目录
1.前文
问题:为什么《msql高性能》推荐将ip地址转换为整数,用一个无符号的32位的整数存储?
理由:(优点)可以节省空间和提高性能,(缺点)但是不利于阅读。
2.MySQL的转换方式
2-1:MySQL提供了INET_ATON函数和INET_NTOA函数作为技术支持;
2-2:INET_ATON:MySQL中的此函数将IPv4地址的dotted-quad表示形式作为字符串,并以整数形式返回给定IP地址的数值。如果输入地址不是有效的IPv4地址,则此函数返回NULL。返回地址由以下公式计算:如果给定的输入IPv4地址是a.b.c.d,则返回值a×2563 + b×2562 + c×2561 + d;
2-3:INET_NTOA:MySQL中的此函数以网络字节顺序获取IPv4地址,然后以dotted-quad字符串表示形式返回该地址。如果输入地址是无效的IPv4地址,则此函数返回NULL。
select INET_ATON('192.168.0.1');
-- 转换后:3232235521
select INET_NTOA(3232235521);
-- 转换后:192.168.0.1
3.JAVA的转换方式
3.1:<< : 左移运算符,空位补0
/**
* 192<<0:192*1=192
* 192<<1:192*2=384
* 192<<2:192*4=768
* 192<<3:192*8=1536
* 192<<4:192*16=3072
* 192<<5:192*32=6144
* 规律:192<<x:192*(x的幂次方),如192<<2=192*(2*2),192<<3=192*(2*2*2)
*/
3.2:>> : 算术右移运算符,空位补最高位值
/**
* 192>>0:192/1=192
* 192>>1:192/2=96
* 192>>2:192/4=48
* 192>>3:192/8=24
* 192>>4:192/16=12
* 192>>5:192/32=6
* 规律:192>>x:192/(x的幂次方),如192>>2=192/(2*2),192>>3=192/(2*2*2)
*/
3.3:>>> : 逻辑右移运算符,空位补0
对于正数而言,>>和>>>没有区别。
对于负数而言:
-2>>>1,结果是2147483647(Integer.MAX_VALUE)
-1>>>1,结果是2147483647(Integer.MAX_VALUE)
如果要判断两个数符号是否相同时,可以这么干:return ((a >> 31) ^ (b >> 31)) ==0;
3.4:例子如下
package com.alex.examples.utils;
/**
* IP转换工具类
*/
public class IpLongUtils {
/**
* 把字符串IP转换成long
*
* @param ipStr 字符串IP
* @return IP对应的long值
*/
public static long ip2Long(String ipStr) {
String[] ip = ipStr.split("\\.");
return (Long.valueOf(ip[0]) << 24) + (Long.valueOf(ip[1]) << 16)
+ (Long.valueOf(ip[2]) << 8) + Long.valueOf(ip[3]);
}
/**
* 把IP的long值转换成字符串
*
* @param ipLong IP的long值
* @return long值对应的字符串
*/
public static String long2Ip(long ipLong) {
StringBuilder ip = new StringBuilder();
ip.append(ipLong >>> 24).append(".");
ip.append((ipLong >>> 16) & 0xFF).append(".");
ip.append((ipLong >>> 8) & 0xFF).append(".");
ip.append(ipLong & 0xFF);
return ip.toString();
}
public static void main(String[] args) {
System.out.println("ip转整数型:" + ip2Long("192.168.0.1"));
System.out.println("整数型转ip:" + long2Ip(3232235521L));
}
}
效果如下:
ip转整数型:3232235521
整数型转ip:192.168.0.1