I have a variable that contains a 4 byte, network-order IPv4 address (this was created using pack and the integer representation). I have another variable, also a 4 byte network-order, subnet. I'm trying to add them together and add one to get the first IP in the subnet.
我有一个包含4字节网络顺序IPv4地址的变量(这是使用pack和整数表示创建的)。我有另一个变量,也是一个4字节的网络顺序子网。我正在尝试将它们添加到一起并添加一个以获取子网中的第一个IP。
To get the ASCII representation, I can do inet_ntoa($ip&$netmask)
to get the base address, but it's an error to do inet_ntoa((($ip&$netmask)+1)
; I get a message like:
要获得ASCII表示,我可以使用inet_ntoa($ ip&$ netmask)来获取基址,但是执行inet_ntoa(($ ip&$ netmask)+1)是错误的;我收到如下消息:
Argument "\n\r&\0" isn't numeric in addition (+) at test.pm line 95.
So what's happening, the best as I can tell, is it's looking at the 4 bytes, and seeing that the 4 bytes don't represent a numeric string, and then refusing to add 1.
所以正在发生的事情,我能说的最好的是,它正在查看4个字节,并看到4个字节不代表数字字符串,然后拒绝添加1。
Another way of putting it: What I want it to do is add 1 to the least significant byte, which I know is the 4th byte? That is, I want to take the string \n\r&\0
and end up with the string \n\r&\1
. What's the simplest way of doing that?
放置它的另一种方法:我想要它做的是将最低有效字节加1,我知道是第4个字节?也就是说,我想取字符串\ n \ r&\ 0并以字符串\ n \ r&1结束。这样做最简单的方法是什么?
Is there a way to do this without having to unpack and re-pack the variable?
有没有办法做到这一点,而无需解压缩和重新包装变量?
2 个解决方案
#1
13
What's happening is that you make a byte string with $ip&$netmask
, and then try to treat it as a number. This is not going to work, as such. What you have to feed to inet_ntoa
is.
发生的事情是你使用$ ip和$ netmask创建一个字节字符串,然后尝试将其视为一个数字。这不会起作用。你必须提供给inet_ntoa的是什么。
pack("N", unpack("N", $ip&$netmask) + 1)
I don't think there is a simpler way to do it.
我认为没有更简单的方法可以做到这一点。
#2
8
Confusing integers and strings. Perhaps the following code will help:
令人困惑的整数和字符串。也许以下代码将有所帮助:
use Socket;
$ip = pack("C4", 192,168,250,66); # why not inet_aton("192.168.250.66")
$netmask = pack("C4", 255,255,255,0);
$ipi = unpack("N", $ip);
$netmaski = unpack("N", $netmask);
$ip1 = pack("N", ($ipi&$netmaski)+1);
print inet_ntoa($ip1), "\n";
Which outputs:
192.168.250.1
#1
13
What's happening is that you make a byte string with $ip&$netmask
, and then try to treat it as a number. This is not going to work, as such. What you have to feed to inet_ntoa
is.
发生的事情是你使用$ ip和$ netmask创建一个字节字符串,然后尝试将其视为一个数字。这不会起作用。你必须提供给inet_ntoa的是什么。
pack("N", unpack("N", $ip&$netmask) + 1)
I don't think there is a simpler way to do it.
我认为没有更简单的方法可以做到这一点。
#2
8
Confusing integers and strings. Perhaps the following code will help:
令人困惑的整数和字符串。也许以下代码将有所帮助:
use Socket;
$ip = pack("C4", 192,168,250,66); # why not inet_aton("192.168.250.66")
$netmask = pack("C4", 255,255,255,0);
$ipi = unpack("N", $ip);
$netmaski = unpack("N", $netmask);
$ip1 = pack("N", ($ipi&$netmaski)+1);
print inet_ntoa($ip1), "\n";
Which outputs:
192.168.250.1