为什么 ping 192.168.072(仅 2 个点)会返回来自 192.168.0.58 的响应?

为什么 ping 192.168.072(仅 2 个点)会返回来自 192.168.0.58 的响应?

我错误地漏掉了 IP 地址上的点,输入了192.168.072
令我惊讶的是,我连接到了一台机器192.168.0.58

如果我 ping 的话192.168.072我会收到来自 的回应192.168.0.58

为什么是这样?


我在 Windows 域中的 Windows PC 上。


如果我 ping 的192.168.72话,我会收到 的回应192.168.0.72,因此看来(我最初的错误)中0的 in072很重要。


这个问题本周超级用户问题
阅读博客条目了解更多详情或为博客做贡献你自己

答案1

每个人都用 RFC、IP 类等将其复杂化。只需运行几个测试,即可查看命令如何ping解析用户输入的 IP(删除无关内容):

> ping 1
Pinging 0.0.0.1 with 32 bytes of data:

> ping 1.2
Pinging 1.0.0.2 with 32 bytes of data:

> ping 1.2.3
Pinging 1.2.0.3 with 32 bytes of data:

> ping 1.2.3.4
Pinging 1.2.3.4 with 32 bytes of data:

> ping 1.2.3.4.5
Ping request could not find host 1.2.3.4.5. Please check the name and try again.

> ping 255
Pinging 0.0.0.255 with 32 bytes of data:

> ping 256
Pinging 0.0.1.0 with 32 bytes of data:

如您所见,该ping命令(在 Windows 中)允许您使用不同的 IP 地址格式。IPv4 地址可以分解为四个部分(“点分四部分”),如下所示:A.B.C.D,并且该ping命令允许您省略一些部分,填写默认值,0如下所示:

1 part  (ping A)       : 0.0.0.A
2 parts (ping A.B)     : A.0.0.B
3 parts (ping A.B.C)   : A.B.0.C
4 parts (ping A.B.C.D) : A.B.C.D

如果您仅提供一个部分,那么如果它小于 255(八位字节的最大值),它将被视为上述八位字节,但如果它大于 255,则会进行转换并滚动到下一个字段(即)mod 256

存在一些边缘情况,例如提供超过四个部分似乎不起作用(例如,对或pinggoogle.com的 IP 都不起作用)。0.74.125.226.474.125.226.4.0

您还可以使用点分四路形式和平分形式的十六进制表示法,但必须通过0x在每个八位字节前面添加内容来格式化它。


因此,有很多方法可以表示 (IPv4) IP 地址。您可以使用平面或点分四(或点分三、点分双,甚至点分单)格式,并且对于每一种格式,您都可以使用(甚至混合搭配)十进制、八进制和十六进制。例如,您可以用google.com以下方式 ping:

  • google.com  (域名)
  • 74.125.226.4  (点分十进制)
  • 1249763844  (平十进制)
  • 0112.0175.0342.0004  (点分八进制)
  • 011237361004  (平面八进制)
  • 0x4A.0x7D.0xE2.0x04  (虚线十六进制)
  • 0x4A7DE204  (平六角)
  • 74.0175.0xe2.4  (ಠ_ಠ)

(谢天谢地,没有添加二进制符号支持!)


应用

在您的例子中,ping192.168.072使用上表中的第三种格式 ( A.B.0.C),因此您实际上是在 ping 192.168.0.072。此外,由于最后一部分有一个前导零,因此它被视为八进制,十进制为 58。

谜团已揭开。


请注意,虽然 Windowsping命令允许输入多种格式并以可见的方式解释非标准格式,但这并不一定意味着您可以在任何地方使用此类格式。有些程序可能会强制您提供点分四组的所有四个部分,而其他程序可能不允许混合和匹配十进制和八进制,等等。

此外,IPv6 地址进一步使解析逻辑和输入格式的可接受性变得复杂。


附录

系统指出如果您在某个数字中使用了无效字符(例如,使用八进制时的8或,十六进制模式下的 ,等等),那么它足够智能,可以识别该字符并将其解释为字符串(-al?-ic?)URL,而不是数字IP地址。9gping

(作为一个曾多次患过动脉瘤和心脏病的人,我试图编写所谓的“简单”代码来适应呈指数级增长的数据值排列数量,我很欣赏它似乎正确地处理了所有的输入变化;在这种情况下,至少 3 1 +3 2 +3 3 +3 4 =120变化。)

因此,虽然指定会按预期010.020.030.040进行 ping ,但传递给会被视为 URL 而不是 IP 地址——可能存在(但遗憾的是不存在)。换句话说,它会尝试对顶级域 上的域上的子域进行 ping 。但是,由于不是有效的 TLD(如、及其伙伴),因此连接在第一步就失败了。8.16.24.32010.020.030.080pingfoo.bar.baz.com010020030080080.com.net

090.010.010.010当无效字符位于不同的八位字节中时,也会发生同样的事情。同样, 0xf.0xf.0xf.0xfping 15.15.15.15,但0xh1.0x1.0xg0.0f失败。

哦,好吧,我猜这就是你不熟练掌握多种数字基数所得到的后果。

确保始终使用 4 点四组(“40q”?“quady-quad”?“cutie-q”?)地址可能更容易、更安全。

所以继续前进学习一些数字基数。你将能够在聚会上炫耀并成为聚会的焦点,正如人们所说,人分为十种类型:懂二进制的人和不懂二进制的人。

我们甚至不要思考关于 IPv6 地址;我认为它们是 111 个印章之一!!!

答案2

有两个原因:

首先,“0”前缀表示八进制数字。由于 oct(072) = dec(58),所以 192.168.072 = 192.168.58。

其次,IP 地址中的倒数第二个 0 可以删除,因为速记。127.0.1 被解释为 127.0.0.1,而在您的情况下 192.168.58 被解释为 192.168.0.58。

答案3

除了@neu242 关于八进制表示法的重要观点以及 IP 地址可以缩短的观察之外,另一个关键部分是了解如何解释缩短的 IP 地址。

有人可能会天真地猜测,如果四个数字中有一些缺失,解析器会在字节序列的末尾(或开头)添加零填充字节。但这与 OP 报告的行为不符:192.168.072 被解析为 192.168。0.58,而不是 192.168.58。0,也不0.192.168.58.

显然,Windows 和 Linux ping(您尝试的版本和我尝试的版本)使用与 inet_aton() 等效的方法来解析 IP 地址参数。inet_aton() 的手册页说:

The address supplied in cp can have one of the following forms:

 a.b.c.d   Each of the four numeric parts specifies a byte of the address; the
           bytes are assigned in left-to-right order to produce the binary
           address.

 a.b.c     Parts a and b specify the first two bytes of the binary address.
           Part c is interpreted as a 16-bit value that defines the rightmost
           two bytes of the binary address.  This notation is suitable for
           specifying (outmoded) Class B network addresses.

 a.b       Part a specifies the first byte of the binary address.  Part b is
           interpreted as a 24-bit value that defines the rightmost three bytes
           of the binary address.  This notation is suitable for specifying
           (outmoded) Class C network addresses.

 a         The value a is interpreted as a 32-bit value that is stored directly
            into the binary address without any byte rearrangement.

因此,您已经了解...192.168.072符合 abc 模式,因此072(解析为八进制数后)被解释为一个 16 位值,定义二进制地址最右边的 2 个字节,相当于0.58

上述规则相当于说,如果四个数字中任何一个缺失,则添加所需的零填充字节紧接在最后一个给出的数字之前... 既不在字节串的末尾,也不在字节串的开头。(如果给出的最后一个数字小于 256,则以这种方式表达有效。)

请注意,较新版本的 ping 可能不允许这种简写,也不允许八进制解释。2010 iputils 源代码我发现,包括 ping 在内,它使用 inet_pton() 而不是 inet_aton() 来解析 IP 地址参数。inet_pton() 的手册页说:

与 inet_aton(3) 和 inet_addr(3) 不同,inet_pton() 支持 IPv6 地址。另一方面,inet_pton() 仅接受点分十进制表示法的 IPv4 地址,而 inet_aton(3) 和 inet_addr(3) 允许更通用的数字和点表示法(十六进制和八进制数字格式,以及不需要显式写入所有四个字节的格式)。

答案4

您还必须考虑到,ip 可以用按其位置意义相加的整数来表示。

192.168.0.58 is :
  192 * 256^3
+ 168 * 256^2
+   0 * 256^1
+  58 * 256^0

这是很酷的事情:

192.168.58 将是 192.168.0.58,因为

    0 * 256^1 
+  58 * 256^0 
=  58

192.11010106 也将是 192.168.0.58,因为

  168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 11010106

3232235578 也将是 192.168.0.58,因为

  192 * 256^3 
+ 168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 3232235578

相关内容