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 相关文章推荐
php与mysql建立连接并执行SQL语句的代码
Jul 04 PHP
PHP中usort在值相同时改变原始位置问题的解决方法
Nov 27 PHP
PHP中time(),date(),mktime()区别介绍
Sep 28 PHP
php字符编码转换之gb2312转为utf8
Oct 28 PHP
php实现httpclient类示例
Apr 08 PHP
fckeditor上传文件按日期存放及重命名方法
May 22 PHP
PHP中使用OpenSSL生成证书及加密解密
Feb 05 PHP
php获取文章内容第一张图片的方法示例
Jul 03 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
Aug 17 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
Dec 05 PHP
php中yii框架实例用法
Dec 22 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防止SQL注入详解及防范
2013/11/12 PHP
超详细的php用户注册页面填写信息完整实例(附源码)
2015/11/17 PHP
yii2.0整合阿里云oss上传单个文件的示例
2017/09/19 PHP
Laravel第三方包报class not found的解决方法
2019/10/13 PHP
PHP7 弃用功能
2021/03/09 PHP
Js 获取HTML DOM节点元素的方法小结
2009/04/24 Javascript
javascript 面向对象编程 聊聊对象的事
2009/09/17 Javascript
Extjs TriggerField在弹出窗口显示不出问题的解决方法
2010/01/08 Javascript
jquery插件jTimer(jquery定时器)使用方法
2013/12/23 Javascript
jQuery中wrapInner()方法用法实例
2015/01/16 Javascript
javascript实现unicode与ASCII相互转换的方法
2015/12/10 Javascript
jQuery通过ajax快速批量提交表单数据
2016/10/25 Javascript
Bootstrap源码解读排版(1)
2016/12/23 Javascript
jquery单击文字或图片内容放大并居中显示
2017/06/23 jQuery
vue中使用localstorage来存储页面信息
2017/11/04 Javascript
bootstrap-Treeview实现级联勾选
2017/11/23 Javascript
Vue 去除路径中的#号
2018/04/19 Javascript
Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例
2017/08/18 Python
使用Python实现租车计费系统的两种方法
2018/09/29 Python
CSS中越界问题的经典解决方案【推荐】
2016/04/19 HTML / CSS
中间件的定义
2016/08/09 面试题
Ruby如何定义一个类
2012/10/08 面试题
教师自我鉴定
2013/12/13 职场文书
事业单位请假制度
2014/01/13 职场文书
物流业务员岗位职责
2014/02/08 职场文书
《搭石》教学反思
2014/04/07 职场文书
小学数学教学经验交流材料
2014/05/22 职场文书
HR求职自荐信范文
2014/06/21 职场文书
党课心得体会范文
2014/09/09 职场文书
2014年园林绿化工作总结
2014/12/11 职场文书
特岗教师个人总结
2015/02/10 职场文书
护林员个人总结
2015/03/04 职场文书
单位领导婚礼致辞
2015/07/28 职场文书
消防安全主题班会
2015/08/12 职场文书
tensorflow中的梯度求解及梯度裁剪操作
2021/05/26 Python
php去除数组中为0的元素的实例分析
2021/11/17 PHP