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 安装方法
Jan 15 PHP
PHP开启gzip页面压缩实例代码
Mar 11 PHP
php使用百度天气接口示例
Apr 22 PHP
php的ddos攻击解决方法
Jan 08 PHP
PHP微信公众号自动发送红包API
Jun 01 PHP
Python中使用django form表单验证的方法
Jan 16 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
Mar 05 PHP
PHP实现通过CURL上传文件功能示例
May 30 PHP
PHP+ajax实现二级联动菜单功能示例
Aug 10 PHP
PHP whois查询类定义与用法示例
Apr 03 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
Apr 16 PHP
php实现对文件压缩简单的方法
Sep 29 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错误日志 display_errors与log_errors的区别
2012/10/09 PHP
关于Javascript 的 prototype问题。
2007/01/03 Javascript
javascript使用activex控件的代码
2011/01/27 Javascript
json2.js的初步学习与了解
2011/10/06 Javascript
javaScript中with函数用法实例分析
2015/06/08 Javascript
浅析JS原型继承与类的继承
2016/04/07 Javascript
Bootstrap每天必学之标签页(Tab)插件
2020/08/09 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
微信小程序 购物车简单实例
2016/10/24 Javascript
纯js实现悬浮按钮组件
2016/12/17 Javascript
网页中的图片查看器viewjs使用方法
2017/07/11 Javascript
详解Vue iview IE浏览器不兼容报错(Iview Bable polyfill)
2019/01/07 Javascript
js实现json数组分组合并操作示例
2019/02/12 Javascript
js 使用ajax设置和获取自定义header信息的方法小结
2020/03/12 Javascript
微信小程序实现自定义动画弹框/提示框的方法实例
2020/11/06 Javascript
Python实现类继承实例
2014/07/04 Python
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
selenium python浏览器多窗口处理代码示例
2018/01/15 Python
python3连接MySQL数据库实例详解
2018/05/24 Python
python使用webdriver爬取微信公众号
2018/08/31 Python
python 获取图片分辨率的方法
2019/01/08 Python
django搭建项目配置环境和创建表过程详解
2019/07/22 Python
django之从html页面表单获取输入的数据实例
2020/03/16 Python
利用Python实现某OA系统的自动定位功能
2020/05/27 Python
Python容器类型公共方法总结
2020/08/19 Python
matplotlib 三维图表绘制方法简介
2020/09/20 Python
python中Mako库实例用法
2020/12/31 Python
五分钟学会怎么用python做一个简单的贪吃蛇
2021/01/12 Python
canvas画布实现手写签名效果的示例代码
2019/04/23 HTML / CSS
canvas如何绘制钟表的方法
2017/12/13 HTML / CSS
struct与class的区别
2014/02/03 面试题
MySQL面试题
2014/01/12 面试题
汇源肾宝广告词
2014/03/20 职场文书
岗位廉政承诺书
2014/03/27 职场文书
青春奉献演讲稿
2014/05/08 职场文书
竞选稿之小学班干部
2019/10/31 职场文书