详谈php ip2long 出现负数的原因及解决方法

php提供了ip2long与long2ip方法对ip地址处理。

1、ip2long — 将一个IPV4的字符串互联网协议转换成数字格式

int ip2long ( string $ip_address )

参数: ip_address 一个标准格式的地址。

返回值: 返回IP地址转换后的数字 或 FALSE 如果 ip_address 是无效的。

2、long2ip — 将数字格式转换成一个IPV4的字符串互联网协议

string long2ip ( string $proper_address )

参数: proper_address 长整型的正确地址表示。

返回值: 返回互联网地址作为字符串。

3、使用方法

<?php
$ip = '10.1.1.1';
$ip_long = ip2long($ip);
echo $ip_long.PHP_EOL; // 167837953
echo long2ip($ip_long); // 10.1.1.1
?>

4、出现负数原因及处理方法

当ip地址比较大时,ip2long会出现负数:

<?php
$ip = '192.168.101.100';
$ip_long = ip2long($ip);
echo $ip_long.PHP_EOL; // -1062705820
echo long2ip($ip_long); // 192.168.101.100
?>

原因说明:

IPv4使用无符号32位地址,因此最多有2的32次方减1(4294967295)个地址。书写用4个小数点分开的10进制数。

记为A.B.C.D,例如:192.168.100.100。

IPv4地址每个10进制数都是无符号的字节,范围在0~255,将IPv4地址转为无符号数,其实就是将每个10进制数放在对应的8位上,组成一个4字节的无符号整型。192.168.100.100,192,168在高8位100,100在低8位。

C实现的例子:

#include <stdio.h>

int main(int argc, char** argv)
{
  unsigned int ip_long = (192 << 24) | (168 << 16) | (100 << 8) | 100;
  printf("%u\n", ip_long);
  printf("%d\n", ip_long);

  return 0;
}

fdipzone@ubuntu:~/C$ gcc -o ip2long ip2long.c
fdipzone@ubuntu:~/C$ ./ip2long
3232261220
-1062706076

可以看到,即使ip_long声明是无符号整型,输出时依然需要指明%u来格式化输出为无符号整型。

因为192大于127(二进制为01111111),192(8位)用二进制表示,最高位必然是1。导致这个4字节整型的最高位为1。

虽然ip_long定义为无符号整型,但printf方法是不理会声明的。所以需要使用%u格式化来输出。如果最高位是0,则使用%d即可。

另一个例子:

ip:112.24.55.99

#include <stdio.h>

int main(int argc, char** argv)
{
  unsigned int ip_long = (112 << 24) | (24 << 16) | (55 << 8) | 99;
  printf("%u\n", ip_long);
  printf("%d\n", ip_long);

  return 0;
}
fdipzone@ubuntu:~/C$ gcc -o ip2long ip2long.c
fdipzone@ubuntu:~/C$ ./ip2long
1880635235
1880635235

解决方法:

输出时用%u来格式化为无符号整型。

<?php
$ip = '192.168.101.100';
$ip_long = sprintf('%u',ip2long($ip));
echo $ip_long.PHP_EOL; // 3232261476
echo long2ip($ip_long); // 192.168.101.100
?>

以上这篇详谈php ip2long 出现负数的原因及解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 探讨PHP函数ip2long转换IP时数值太大产生负数的解决方法

    [造成原因]:Because PHP's integer type is signed, and many IP addresses will result in negative integers. [解决办法]:其官方手册中提到,可以"you need to use the "%u" formatter of sprintf() or printf() to get the string representation of the unsigned IP address&

  • 详谈php ip2long 出现负数的原因及解决方法

    php提供了ip2long与long2ip方法对ip地址处理. 1.ip2long - 将一个IPV4的字符串互联网协议转换成数字格式 int ip2long ( string $ip_address ) 参数: ip_address 一个标准格式的地址. 返回值: 返回IP地址转换后的数字 或 FALSE 如果 ip_address 是无效的. 2.long2ip - 将数字格式转换成一个IPV4的字符串互联网协议 string long2ip ( string $proper_address

  • MySQL无法创建外键的原因及解决方法

    关联2张表时出现了无法创建外键的情况,从这个博客看到,问题出在第六点的Charset和Collate选项在表级和字段级上的一致性上.我的2张表的编码charset和collate不一致,2张表都执行执行SQL语句: alter table 表名 convert to character set utf8; 完美解决问题: ps:下面看下MySQL无法创建外键.查询外键的属性 MyISAM 和InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各

  • jQuery通过ajax方法获取json数据不执行success的原因及解决方法

    1.jquery通过ajax方法获取json数据不执行success回调 问题描述:jquery通过ajax方法获取json数据不执行success回调方法 问题原因:json格式存在问题或不符合标准写法,导致总是执行error回调方法 解决方案:使json格式务必符合下述3个标准写法: 1)键名称:用双引号括起: 2)字符串:用双引号括起: 3)数字,布尔值不需要使用双引号括起 : 注意:一定是双括号! 2.jQuery中ajax使用json数据类型总是跳过success执行error语句 执

  • 关于动态生成dom绑定事件失效的原因及解决方法

    之前做项目都是直接用jquery的bind绑定事件,不过当时都不是动态生成dom元素,而是已经页面中原本存在的dom元素进行事件绑定,最近在测试给动态生成的dom绑定事件的时候发现事件失效,于是就测试了一下: 1. 事件失效的原因: (1)bind事件绑定只对dom中存在的元素有效,对于我们后来动态增加的元素是监测不到,所以绑定不了 (2)同样,当你使用var aa = document.getElementsByTagName("动态生成的元素");来获取动态生成的元素的时候也是获取

  • AngularJS使用ng-inlude指令加载页面失败的原因与解决方法

    本文实例讲述了AngularJS使用ng-inlude指令加载页面失败的原因与解决方法.分享给大家供大家参考,具体如下: AngularJS中提供的ng-include指令,很类似于JSP中的<jsp:include>用来将多个子页面合并到同一个父页面中,避免父页面过大,可读性差,不好维护. 父页面parent.html代码如下: <html> <head> <script src="angular-1.2.2/angular.js">&

  • Ubuntu安装telent服务器时出现:apt-get:Package has no installation的原因及解决方法

    当我在终端敲下这条命令的时候,系统就提示telnetd:apt-get:Package has no installation sudo apt-get install xinetd telnetd 刚开始我以为是没有这个包,后来查了一下资料发现,有这个软件,于是百度了一下才知道解决以上问题需要如下操作: # apt-get update # apt-get upgrade # apt-get install <packagename> 这样就可以正常使用apt-get了. 接下来就按照以前转

  • Java内存各部分OOM出现原因及解决方法(必看)

    一,jvm内存区域 1,程序计数器 一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器. 2,java栈 与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同.通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址) 栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常:如果虚拟机栈可以动态扩展(大部分虚拟机都可动

  • VIVO手机上del键无效OnKeyListener不响应的原因及解决方法

    在修改交易密码界面用到一个自定义输入框 类似这种(原谅丑了点~) 结果昨天有用户反馈在VIVO手机上回出现,Del键无效的问题~~~ 最后发现是:EdiText的OnKeyListener没有响应. 最后搜搜了一下,找到了解决方案:重写EdiTextView的InputConnectionWrapper的方法后解决了问题: 代码如下: public class ZanyEditText extends EditText { private OnDelKeyEventListener delKey

  • ajax内部值外部调用不了的原因及解决方法

    ajax内部值外部调用不了的原因及解决方法 var id='123'; $.ajax({ url:'http://www.xxx.com/ajax', type:'post', dataType: "json", data:{wurl:w_url,murl:m_url}, async : turn, error:function(){ }, success:function(data){ var id= data['id']; console.log(id) // 这里出来的是100

  • tomcat6下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法

    1.在tomcat6.0下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 在tomcat6.0下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有妥善处理好的原因. 具体的原因就是: 在tomcat中jsp编译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse res

随机推荐