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简介
Oct 09 PHP
火车头采集器3.0采集图文教程
Mar 17 PHP
PHP面向对象法则
Feb 23 PHP
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
Feb 06 PHP
PHP实现单例模式最安全的做法
Jun 13 PHP
PHP中error_log()函数的使用方法
Jan 20 PHP
CI框架无限级分类+递归的实现代码
Nov 01 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
Dec 02 PHP
PHP/HTML混写的四种方式总结
Feb 27 PHP
php 截取GBK文档某个位置开始的n个字符方法
Mar 08 PHP
一文掌握PHP Xdebug 本地与远程调试(小结)
Apr 23 PHP
PHP使用ActiveMQ实现消息队列的方法详解
May 31 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初学者头痛的十四个问题
2006/07/12 PHP
PHP实现删除字符串中任何字符的函数
2015/08/11 PHP
php post json参数的传递和接收处理方法
2018/05/31 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
用javascript实现的图片马赛克后显示并切换加文字功能
2007/04/21 Javascript
JavaScript学习笔记(十七)js 优化
2010/02/04 Javascript
javascript 静态对象和构造函数的使用和公私问题
2010/03/02 Javascript
JS 自定义函数缺省值的设置方法
2010/05/05 Javascript
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
javascript实现unicode与ASCII相互转换的方法
2015/12/10 Javascript
基于JavaScript如何实现ajax调用后台定义的方法
2015/12/29 Javascript
jQuery实现查找链接文字替换属性的方法
2016/06/27 Javascript
使用cropper.js裁剪头像的实例代码
2017/09/29 Javascript
webpack4打包vue前端多页面项目
2018/09/17 Javascript
Node.js Stream ondata触发时机与顺序的探索
2019/03/08 Javascript
通过layer实现可输入的模态框的例子
2019/09/27 Javascript
JQuery事件冒泡和默认行为代码实例
2020/05/13 jQuery
Python+Django在windows下的开发环境配置图解
2009/11/11 Python
python 实现对文件夹内的文件排序编号
2018/04/12 Python
python数字图像处理之骨架提取与分水岭算法
2018/04/27 Python
对Python 中矩阵或者数组相减的法则详解
2019/08/26 Python
Django自定义YamlField实现过程解析
2020/11/11 Python
python实现简单文件读写函数
2021/02/25 Python
正宗的日本零食和糖果订阅盒:Bokksu
2019/11/21 全球购物
成人大专自我鉴定范文
2013/10/19 职场文书
室内设计专业个人的自我评价
2013/10/19 职场文书
高级护理专业大学生求职信
2013/10/24 职场文书
前台文员我鉴定
2014/01/12 职场文书
顶撞领导检讨书
2014/01/29 职场文书
个人综合鉴定材料
2014/05/23 职场文书
2015毕业寄语大全
2015/02/26 职场文书
2015年生产部工作总结范文
2015/05/25 职场文书
养成教育工作总结
2015/08/13 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书
pycharm debug 断点调试心得分享
2021/04/16 Python
Vue全家桶入门基础教程
2021/05/14 Vue.js