这篇文章主要介绍了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. 循序渐进开发WinForm项目(5)--Excel数据的导入导出操作

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  2. DataTable 获取列名 DataTable批量更新至数据库

    好久没写东西了,这几个月也没下功夫钻研技术,愧疚啊.说下最近刚学会的DataTable 的用法吧,新手适合看下. 1 DataTable 获取列名 在处理数据的时候大家都会用到模型,从datatabl ...

  3. AppCan可以视为Rexsee的存活版

    今天看到地宝的几个APP用appcan做的,我顿时惊呆了. 1. 走的同样是中间件的模式,支持原生UI界面的访问: 2. 在线打包的方式,进行资源的限制,以便商业化支持:

  4. map与vector---Email Aliases

    Description Polycarp has quite recently learned about email aliases. Of course, he used to suspect t ...

  5. 泛函编程(19)-泛函库设计-Parallelism In Action

    上节我们讨论了并行运算组件库的基础设计,实现了并行运算最基本的功能:创建新的线程并提交一个任务异步执行.并行运算类型的基本表达形式如下: import java.util.concurrent._ o ...

  6. ANSI X9.19 MAC算法

    /// <summary> /// 获取MAC校验字节数据 /// </summary> /// <param name="bankData"> ...

  7. log4j.xml 配置参数属性level使用心得

    jdbc.sqlonly        只显示执行的sql语句.info级才可以显示,debug增加显示java源代码位置. jdbc.sqltiming    显示执行的sql语句以及语句执行时间, ...

  8. C# 分支语句

    选择语句 if,else if是如果的意思,else是另外的意思,if后面跟()括号内为判断条件,如果符合条件则进入if语句执行命令.如果不符合则不进入if语句.else后不用加条件,但是必须与if配 ...

  9. HTML5中的音视频处理

    * 音视频处理 * 视频处理 * 基本内容 * 使用Flash技术处理HTML页面中的视频内容 * 包含音频.动画.网页游戏等 * 特点 * 浏览器原生不支持(IE浏览器要求安装ActiveX组件) ...

  10. Vue方法与事件

    gitHub地址:https://github.com/lily1010/vue_learn/tree/master/lesson10 一 vue方法实现 <!DOCTYPE html> ...