MySQL如何存储IP地址, Java和PHP IP地址与int或者long类型互转

2019-02-16 07:48:09   MySQL

对数据库了解的同学都知道数字类型其实是要比字符串类型的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 为例,四段分别是101812,用8bit的二进制表示分别为00001010000000010000100000001100,其中不足8位的数字用0在左边补齐。
  • 最后我们要的结果其实是00001010000000010000100000001100,也就是按照顺序,拼接起来,转为十进制位167839756(我口算的,你们信不;-))。
  • 我们依次从左到右这四段,分别左移24位、16位、8位、0位,Java中位用逻辑左移运算符<< ,然后我们可以得到00001010000000000000000000000000000000010000000000000000 , 0000110000000000, 00001100
  • 最后我们将这几段二进制数做或操作,Java中逻辑或运算符为| (有一个为1则此位为1)于是我们就可以得到00001010000000010000100000001100 , 十进制就是167839756.

如何还原

  • 明白了如何拼装的之后,我们还原就很容易了
  • 我们把这个长长的数字右移,分别把00001010000000010000100000001100 右移24位、16位、8位、0位,然后得到00001010000010100000000100001010000000010000100000001010000000010000100000001100
  • 然后,我们用11111111 也就是 0xFF 来跟上述的四段数字以此做与操作,java中运算符位& (同1为1,有一个为0则此位为0), 我们就可以得到00001010000000010000100000001100,十进制依次为:101812,最后中间加点,就还原了。
  • 这个与操作实际上就是起到了截断的作用,只取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转为long
long2ip() 将 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.我爱你

viencoding.com版权所有,允许转载,但转载请注明出处和原文链接: https://viencoding.com/article/34
欢迎小伙伴们在下方评论区留言 ~ O(∩_∩)O
文章对我有帮助, 点此请博主吃包辣条 ~ O(∩_∩)O

猜你喜欢


评论

There are no comments yet.
未登录

登录后即可发表评论

登录或注册

标签

AdSense Anaconda Android apache API apt Auth AWS B-tree Bandwagon Blog bower brew bytes Caffe Catalina certbot cloudcone Composer conda CoreML CPU crontab CSS csv Cuda cv2 datetime Digitalocean DNS Docker Docker-Compose Eloquent Excel export Flask FTP GET Git GitHub GitLab Gmail GoDaddy Google GTM hash Homebrew Homestead HTML http HTTPS IDEA image imagemagick imagick imgick import InnoDB ios iou iPhone ISO8601 iTerm2 Java JavaScript JPG JS Keras Laravel Laravel-Admin lazyload Linux list Livewire lnmp load logs Lravel Mac Markdown matplotlib md5 mix MobileNet Mojave mongo MongoDB MySQL Namesilo Nginx Node npm numpy Nvidia Nvidia-Docker onevps OpenCV Openpose openpyxl oss Outline parse PayPal PHP php-fpm PhpStorm PHP扩展 PIL Pillow pip PNG POST Protobuf PyCharm pyenv pymongo Python Python,人工智能,机器学习,VOC,xml Queue Redis requests RGB Sanctum save selenium SEO Shadowsock Shadowsocks ShadowsocksR simplemde Spring Boot SQLServer ssd SSH ssl SSL证书 SSR str Sublime sudo swap Swift Tensorflow TensorflowLite Terminal Terminator timestamp Ubuntu urllib UTC v2ray Valet Validation Validator VienBlog virtualenvs VPN VPS Vultr Web Windows WordPress Xcode xlsx yaml YAPI YUV zip zmq zsh 下载图片 主从同步 云主机 云存储 云开发 云服务器 人工智能 优化 优惠码 伪原创 作弊与反作弊 免费ss账号 免费提现 切片 前端 加密 协议 博客 友链 双击事件 后台运行 后端 命令 国内镜像源 图标 图片操作 图片转换 域名 多身份认证 大小写转换 姿态检测 安卓模拟器 安装 定时任务 定时执行 密码 密钥 导出导入 小程序码 延迟加载 异常 微信 微信小程序 快捷方式 慢查询 懒加载 提现 搜索引擎 搬瓦工 搭梯子 教程 数据库 数据重复 文件上传 无法登录 日志 日期 时区 时间 时间戳 服务器 机器学习 权限 梯子 模拟浏览器 港版支付宝 漏洞 爬虫 生活服务 用户管理 病毒 登录 目标检测 科学上网 系统升级 索引 组件 组件开发 编辑器 自动付款 自定义组件 英文伪原创 计划任务 计算机视觉 订阅通知 认证 语法 读写分离 远程连接 配置文件 重定向 错误异常 错误提示 队列 阿里云 香港 香港手机号
亲情非友情链接