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文件上传实例详解!!!
Jan 02 PHP
mac下使用brew配置环境的步骤分享
May 23 PHP
php数组函数序列之rsort() - 对数组的元素值进行降序排序
Nov 02 PHP
php一个找二层目录的小东东
Aug 02 PHP
yii中widget的用法
Dec 03 PHP
使用Huagepage和PGO来提升PHP7的执行性能
Nov 30 PHP
php实现异步数据调用的方法
Dec 24 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
Jan 22 PHP
php版微信开发之接收消息,自动判断及回复相应消息的方法
Sep 23 PHP
PHP使用curl制作简易百度搜索
Nov 03 PHP
Zend Framework过滤器Zend_Filter用法详解
Dec 09 PHP
php实现的XML操作(读取)封装类完整实例
Feb 23 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
ThinkPHP做文字水印时提示call an undefined function exif_imagetype()解决方法
2014/10/30 PHP
php中解析带中文字符的url函数分享
2015/01/20 PHP
php计算指定目录下文件占用空间的方法
2015/03/13 PHP
php实现贪吃蛇小游戏
2016/07/26 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
如何取得中文输入的真实长度?
2006/06/24 Javascript
Javascript技巧之不要用for in语句对数组进行遍历
2010/10/20 Javascript
利用jQuery操作对象数组的实现代码
2011/04/27 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
2011/06/27 Javascript
js实现window.open不被拦截的解决方法汇总
2014/10/30 Javascript
JavaScript实现SHA-1加密算法的方法
2015/03/11 Javascript
JavaScript操作Cookie方法实例分析
2015/05/27 Javascript
js+css实现文字散开重组动画特效代码分享
2015/08/21 Javascript
JavaScript设置、获取、清除单值和多值cookie的方法
2015/11/17 Javascript
js操作cookie保存浏览记录的方法
2015/12/25 Javascript
JS实现简单的tab切换选项卡效果
2016/09/21 Javascript
React Native仿美团下拉菜单的实例代码
2017/08/08 Javascript
ligerUI---ListBox(列表框可移动的实例)
2017/11/28 Javascript
微信公众号H5之微信分享常见错误和问题(小结)
2019/11/14 Javascript
python实现基于两张图片生成圆角图标效果的方法
2015/03/26 Python
Python使用正则表达式过滤或替换HTML标签的方法详解
2017/09/25 Python
Python入门之后再看点什么好?
2018/03/05 Python
浅析Python 实现一个自动化翻译和替换的工具
2019/04/14 Python
python opencv进行图像拼接
2020/03/27 Python
CSS3与动画有关的属性transition、animation、transform对比(史上最全版)
2017/08/18 HTML / CSS
荷兰网上药店:Drogisterij.net
2019/09/03 全球购物
办公室前台的岗位职责
2013/12/20 职场文书
校园广播稿500字
2014/02/04 职场文书
计算机专业求职信
2014/06/02 职场文书
班训口号大全
2014/06/18 职场文书
2014年煤矿工作总结
2014/11/24 职场文书
伏羲庙导游词
2015/02/09 职场文书
合作协议书格式范本
2016/03/21 职场文书
MySQL Router的安装部署
2021/04/24 MySQL
Mysql调整优化之四种分区方式以及组合分区
2022/04/13 MySQL