PHP中IP地址与整型数字互相转换详解


Posted in PHP onAugust 20, 2014

IP转换成整型存储是数据库优化一大趋势,不少人目前存储IP时还在使用字符串类型存储,字符串索引比整型索引消耗资源很多,特别是表中数据量大的时候,以及求查询某一个ip段的数据,今天说的ip是指ip4,ip6不在本文范围内。

系统函数ip2long与long2ip
PHP中有内置函数ip2long可以将ip地址转换整型。

$ip = '210.110.11.49';

echo ip2long($ip);

输出:
-764540111

输出的整型有负号是因为我们得到的结果是有符号整型,有符号整型最大值2147483647,要把结果转换为无符号型可以这么写:
3530427185

使用long2ip把整型转换回ip地址

$ip = '210.110.11.49';

$ip_int = ip2long($ip);

echo $ip."<br />";

echo $ip_int."<br />";

echo long2ip($ip_int);

输出:
210.110.11.49

-764540111

210.110.11.49

从结果可以看到,ip与整型可以通过函数完成。

系统函数小bug

这中bug网上一搜都是,大意说的是ip某段加个前导0,先来看看这个bug实例

$ip = '210.110.011.49';

$ip_int = ip2long($ip);

echo $ip."<br />";

echo $ip_int."<br />";

echo long2ip($ip_int);

输出:
210.110.011.49

-764540623

210.110.9.49

转换结果不匹配,我们试着在ip第一段数字前加前导0,再看看

$ip = '021.110.11.49';

$ip_int = ip2long($ip);

echo $ip."<br />";

echo $ip_int."<br />";

echo long2ip($ip_int);

输出:
021.110.11.49

292424497

17.110.11.49

转换结果都出错。以上例子都是因为加了前导0后导致转换结果出错,连带逆转结果与原转换ip不匹配。

转换原理

目前有两个算法:
第一、第一段乘以256的三次方,第二段乘以256的平方,第三段乘以256、最后总和

$ip = '0210.110.11.49';

 

function ipToInt($ip){

    $iparr = explode('.',$ip);

    $num = 0;

    for($i=0;$i<count($iparr);$i++){

        $num += intval($iparr[$i]) * pow(256,count($iparr)-($i+1));

    }

    return $num;

}

 

echo  $ip.'<br />';

$ip_int = ipToInt($ip);

echo $ip_int.'<br />';

echo long2ip($ip_int);

输出:
0210.110.11.49

3530427185

210.110.11.49

第二、通过位运算符

$ip = '0210.110.11.49';

 

function ipToInt($ip){

    $iparr = explode('.',$ip);

    return (intval($iparr[0]<<24))|(intval($iparr[1])<<16)|(intval($iparr[2])<<8)| (intval($iparr[3]));

}

 

echo  $ip.'<br />';

$ip_int = ipToInt($ip);

echo $ip_int.'<br />';

echo long2ip($ip_int);

输出:
0210.110.11.49

-764540111

210.110.11.49

检测IP是否合法

第一、自己遍历检测

function check_ip($ip){

    $iparr = explode('.',$ip);

    foreach($iparr as $v){ if($v>255) return false; }

    return true;

}

 

echo '210.285.11.49,';

var_dump(check_ip('210.285.11.49'));

echo '<br />';

echo '210.205.11.49,';

var_dump(check_ip('210.205.11.49'));

[code]
输出:

[code]

210.285.11.49,bool(false)

210.205.11.49,bool(true)

第二、使用ip2long返回
function check_ip($ip){

    if(ip2long($ip)) return true;

    return false;

}

 

echo '210.285.11.49,';

var_dump(check_ip('210.285.11.49'));

echo '<br />';

echo '210.205.11.49,';

var_dump(check_ip('210.205.11.49'));

输出:
210.285.11.49,bool(false)

210.205.11.49,bool(true)

后记

不少人把ip写库用ip2long转换存放int类型的字段中,但是,在不同的系统平台上,ip2long函数得到的值是不同的,因此可能造成在从数据库中读出数据逆转ip时用long2ip得到的ip与原ip不符合
如果是mysql可以使用mysql系统函数INET_ATON与INET_NTOA解决,或者使用bigint类型处理,要么自己写函数。

PHP 相关文章推荐
杏林同学录(三)
Oct 09 PHP
php a simple smtp class
Nov 26 PHP
php smarty截取中文字符乱码问题?gb2312/utf-8
Nov 07 PHP
PHP中文件缓存转内存缓存的方法
Dec 06 PHP
PHP获取MSN好友列表类的实现代码
Jun 23 PHP
php上传文件,创建递归目录的实例代码
Oct 18 PHP
PHP基于cookie与session统计网站访问量并输出显示的方法
Jan 15 PHP
PHP全局变量与超级全局变量区别分析
Apr 01 PHP
PDO的安全处理与事物处理方法
Oct 31 PHP
PHP实现的服务器一致性hash分布算法示例
Aug 09 PHP
laravel excel 上传文件保存到本地服务器功能
Nov 14 PHP
yii2.0框架数据库操作简单示例【添加,修改,删除,查询,打印等】
Apr 13 PHP
PHP函数http_build_query使用详解
Aug 20 #PHP
PHP函数in_array()使用详解
Aug 20 #PHP
PHP中使用json数据格式定义字面量对象的方法
Aug 20 #PHP
PHP采用自定义函数实现遍历目录下所有文件的方法
Aug 19 #PHP
浅谈php函数serialize()与unserialize()的使用方法
Aug 19 #PHP
PHP将回调函数作用到给定数组单元的方法
Aug 19 #PHP
php实现文件下载代码分享
Aug 19 #PHP
You might like
php提示Call-time pass-by-reference has been deprecated in的解决方法[已测]
2012/05/06 PHP
php截取字符串并保留完整xml标签的函数代码
2013/02/06 PHP
如何批量替换相对地址为绝对地址(利用bat批处理实现)
2013/05/27 PHP
关于使用key/value数据库redis和TTSERVER的心得体会
2013/06/28 PHP
解决在Laravel 中处理OPTIONS请求的问题
2019/10/11 PHP
jQuery统计上传文件大小的方法
2015/01/24 Javascript
jQuery实现在textarea指定位置插入字符或表情的方法
2015/03/11 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
「中高级前端面试」JavaScript手写代码无敌秘籍(推荐)
2019/04/08 Javascript
vue elementUI 表单校验功能之数组多层嵌套
2019/06/04 Javascript
[10:24]郎朗助力完美“圣”典,天籁交织奏响序曲
2016/12/18 DOTA
浅谈Python单向链表的实现
2015/12/24 Python
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
python实现音乐下载器
2018/04/15 Python
解决python报错MemoryError的问题
2018/06/26 Python
python+pyqt5实现24点小游戏
2019/01/24 Python
django的ORM模型的实现原理
2019/03/04 Python
Python QQBot库的QQ聊天机器人
2019/06/19 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
Python3 字典dictionary入门基础附实例
2020/02/10 Python
Django使用list对单个或者多个字段求values值实例
2020/03/31 Python
python:解析requests返回的response(json格式)说明
2020/04/30 Python
Django如何继承AbstractUser扩展字段
2020/11/27 Python
详解纯CSS3制作的20种loading动效
2017/07/05 HTML / CSS
阿提哈德航空官方网站:Etihad Airways
2017/01/06 全球购物
Gweniss格温妮丝女包官网:英国纯手工制造潮流包包品牌
2018/02/07 全球购物
介绍一下.net和Java的特点和区别
2012/09/26 面试题
JAVA程序员自荐书
2014/01/30 职场文书
公司司机岗位职责范本
2014/03/03 职场文书
保研推荐信
2014/05/09 职场文书
有关九一八事变的演讲稿
2014/09/14 职场文书
董事长助理岗位职责
2015/02/11 职场文书
OpenCV绘制圆端矩形的示例代码
2021/08/30 Python
Apache POI的基本使用详解
2021/11/07 Servers