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 相关文章推荐
用 PHP5 轻松解析 XML
Dec 04 PHP
基于PHP5魔术常量与魔术方法的详解
Jun 13 PHP
使用PHP获取汉字的拼音(全部与首字母)
Jun 27 PHP
php中AES加密解密的例子小结
Feb 18 PHP
php+mysql大量用户登录解决方案分析
Dec 29 PHP
YII Framework框架教程之国际化实现方法
Mar 14 PHP
Netbeans 8.2与PHP相关的新特性介绍
Oct 08 PHP
php curl 模拟登录并获取数据实例详解
Dec 22 PHP
PHP递归实现汉诺塔问题的方法示例
Nov 25 PHP
PHP缓存工具XCache安装与使用方法详解
Apr 09 PHP
PHP排序算法之归并排序(Merging Sort)实例详解
Apr 21 PHP
PHP实现压缩图片尺寸并转为jpg格式的方法示例
May 10 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 Google的translate API代码
2008/12/10 PHP
提高PHP编程效率的53个要点(经验小结)
2010/09/04 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十)
2014/06/24 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
PHP receiveMail实现收邮件功能
2018/04/25 PHP
phpstudy隐藏index.php的方法
2020/09/21 PHP
window.showModalDialog参数传递中含有特殊字符的处理方法
2013/06/06 Javascript
用js实现输入提示(自动完成)的实例代码
2013/06/14 Javascript
js简单实现根据身份证号码识别性别年龄生日
2013/11/29 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2015/04/01 Javascript
深入理解JS函数的参数(arguments)的使用
2016/05/28 Javascript
谈谈target=_new和_blank的不同之处
2016/10/25 Javascript
JavaScript引用类型Array实例分析
2018/07/24 Javascript
vue: WebStorm设置快速编译运行的方法
2018/10/18 Javascript
element ui table(表格)实现点击一行展开功能
2018/12/04 Javascript
你不可不知的Vue.js列表渲染详解
2019/10/01 Javascript
JS获取表格视图所选行号的ids过程解析
2020/02/21 Javascript
uni-app使用countdown插件实现倒计时
2020/11/01 Javascript
[29:16]完美世界DOTA2联赛决赛日 Inki vs LBZS 第三场 11.08
2020/11/10 DOTA
python有证书的加密解密实现方法
2014/11/19 Python
Python中类型关系和继承关系实例详解
2015/05/25 Python
Python深入06——python的内存管理详解
2016/12/07 Python
Python sql注入 过滤字符串的非法字符实例
2020/04/03 Python
基于Python和C++实现删除链表的节点
2020/07/06 Python
解决pip安装tensorflow中出现的no module named tensorflow.python 问题方法
2021/02/20 Python
学校后勤人员职责
2013/12/27 职场文书
公司党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
离婚协议书怎么写(范本参考)
2014/09/30 职场文书
机关作风建设剖析材料
2014/10/11 职场文书
优秀班主任先进事迹材料
2014/12/16 职场文书
家属慰问信
2015/02/14 职场文书
教师党员自我评价范文
2015/03/04 职场文书
2016年党员学习廉政准则心得体会
2016/01/20 职场文书
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python
浅谈css实现背景颜色半透明的两种方法
2021/12/06 HTML / CSS