这篇文章主要介绍了PHP中IP地址与整型数字互相转换详解,本文介绍了使用PHP函数ip2long与long2ip的使用,以及它们的BUG介绍,最后给出自己写的两个算法,需要的朋友可以参考下

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.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中IP地址与整型数字互相转换详解的更多相关文章

  1. IP地址后面斜杠加具体数字详解

    其实这种形式就是用CIDR(无类别域间路由选择,Classless and Subnet Address Extensions and Supernetting))的形式表示的一个网段,或者说子网. ...

  2. java中Array/List/Map/Object与Json互相转换详解

    http://blog.csdn.net/xiaomu709421487/article/details/51456705 JSON(JavaScript Object Notation): 是一种轻 ...

  3. java中Array/List/Map/Object与Json互相转换详解(转载)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Langu ...

  4. JAVA中时间格式(SimpleDateFormat)和数字格式(DecimalFormat)转换详解(转)

    时间格式转换SimpleDateFormat: //定义日期的格式 SimpleDateFormat format =new SimpleDateFormat("yyMMdd"); ...

  5. JAVA中list,set,map与数组之间的转换详解

    package test; import java.util.*; /** * Created by ming */ public class Test { public static void ma ...

  6. 求一个整型数字中有没有相同的部分,例如12386123这个整型数字中相同的部分是123,相同的部分至少应该是2位数,如果有相同部分返回1,如果没有则返回0。方法是先将整型数字转换到数组中,再判断。函数为 int same(int num)其中num是输入的整型数字

    import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Test { pub ...

  7. Java 判断是否为汉字 判断是否为乱码 判断字符串是否为双整型数字 整数 数字

    /**  * 判断是否为汉字  *   * @param str  * @return  */ public static boolean isGBK(String str) {  char[] ch ...

  8. Delphi版IP地址与整型互转

    Delphi版IP地址与整型互转 unit Unit11; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphic ...

  9. 【mysql】IP地址整数int和varchar的转换

    mysql中IP地址的存储 IP:如192.168.12.145,在存储时,若是采用varchar进行存储,存在两个主要缺点: 存储空间占用较大: 查询检索较慢: 解决方式: 存储时:将字符串类型的I ...

随机推荐

  1. 第二sprint总结

    总结:在第二轮sprint中,团队的开发工作出现了极大的懈怠,团队成员分配的工作完成情况较差,进度较慢,希望能在最后一周中,完成预定的功能模块 个人贡献分: 124陈彦生:22=20*5*22% 14 ...

  2. 0527Sprint总结,读书笔记与提问

    第八章主要软件团队如何准确全面的找到人们对于软件五花八门的需求,主要有以下几个步骤: 1.获取和引导需求 2.分析和定义需求 3.验证需求 4.在软件产品的生命周期中管理需求 . 接下来讲了软件产品的 ...

  3. 在C#后端处理一些结果然传给前端Javascript或是jQuery

    在C#后端处理一些结果然传给前端Javascript或是jQuery,以前Insus.NET有做过一个例子<把CS值传给JS使用 >http://www.cnblogs.com/insus ...

  4. 优化win2d实现的萤火虫粒子效果

    前几天我发了个技术博客,告诉大家怎样用Win2D 画萤火虫动画 . 那种绘制萤火虫的方式虽然画质高,但是性能不好,萤火虫数量超过50就可以感受到帧数下降. 我今天想到了一种牺牲画质提升性能的绘制方式, ...

  5. foreach---集合已修改;可能无法执行枚举操作。

    小结 : foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等).要避免这个问题,就应该使用for循环--- 原因: 当用foreach遍历Collection时,如果对Collec ...

  6. 【C#进阶系列】03 配置文件管理与程序集的引用版本重定向

    先来点与标题不相关的: CLR支持两种程序集:弱命名程序集和强命名程序集. 两者的区别在于强命名程序集使用发布者的公钥和私钥进行签名.由于程序集被唯一性地标识,所以当应用程序绑定到强命名程序集时,CL ...

  7. 老毛桃安装Win8(哪里不会点哪里,so easy)

    先来一张美女图,是不是很漂亮呢!继续往下看! 英雄不问出路,美女不看岁数!求推荐啊! 每次碰到妹子找我装系统的时候我都毫不犹豫的答应了,心里暗暗想到:好好表现啊!此刻的心情比见家长还要激动和紧张! 有 ...

  8. [转] 基于 Apache Mahout 构建社会化推荐引擎

    来源:http://www.ibm.com/developerworks/cn/java/j-lo-mahout/index.html 推荐引擎简介 推荐引擎利用特殊的信息过滤(IF,Informat ...

  9. ASP.NET MVC进阶一

    一.控制器相关 在Controller类中方法访问级别为public的方法,就是行为(Action). 如果不希望Controller类中的方法成为Action(可以在地址栏中被访问),有两种实现方式 ...

  10. IBATIS动态SQL(转)

    直接使用JDBC一个非常普遍的问题就是动态SQL.使用参数值.参数本身和数据列都是动态SQL,通常是非常困难的.典型的解决办法就是用上一堆的IF-ELSE条件语句和一连串的字符串连接.对于这个问题,I ...