ip和Long进行转换

问题分析

​ 我们会有这样的需求,就是存储用户上次登录的ip地址,那么我们该如何存储到数据库呢?那还不简单,用varchar(15)来存储不就好了,最大的ip也就15位。这样可以。but!! 但是,这样浪费了空间不说(用户量很大的话),如果要判断某个用户的ip是否在某个ip段这样也就不好做了。所以啊。我们可以将ip转换成Long类型也只是占用4个字节,而且方便查询和计算。

如何转换

其实就是将每个位转换成2进制,然后进行位移就好了,如果转换回来也是这样,往回位移然后取最后的一个字节(一位0-255占一个字节8个二进制位)。

话不多说,上代码:

public class IPUtils {
private static final Pattern PATTERN = Pattern.compile("^((2([0-4]\\d|5[0-5])|[01]?\\d{1,2})\\.){3}(2([0-4]\\d|5[0-5])|[01]?\\d{1,2})$");
/**
* ip转换成long
*
* @param ip ip
* @return long
*/
public static Long ipToLong(String ip) {
//校验ip是否正确
Matcher matcher = PATTERN.matcher(ip);
if (!matcher.find()) {
throw new RuntimeException("ip 格式不正确");
}
String[] split = ip.split("\\.");
return (Long.parseLong(split[0]) << 24) + (Long.parseLong(split[1]) << 16)
+ (Long.parseLong(split[2]) << 8) + Long.parseLong(split[3]);
}
/**
* 将long类型转换成ip
*
* @param ipLong ip的long类型
* @return ip
*/
public static String longToIp(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(ipToLong("127.0.0.1"));
System.out.println(longToIp(2130706433L));
}
}

如果你对上面的0xFF感到疑惑的话别急,其实你想啊,0xff不就是255的十六进制吗?换行成二进制不就是1111 1111吗?那么任何数与它做与运算(&)不就是去取这个数的二进制的最后八位吗?所以,我们只是向右位移,然后取最后八个二进制位就还原回来了!!

posted @   敬敬不想造轮子  阅读(823)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示