答案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.4
74.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地址。9
g
ping
(作为一个曾多次患过动脉瘤和心脏病的人,我试图编写所谓的“简单”代码来适应呈指数级增长的数据值排列数量,我很欣赏它似乎正确地处理了所有的输入变化;在这种情况下,至少 3 1 +3 2 +3 3 +3 4 =120变化。)
因此,虽然指定会按预期010.020.030.040
进行 ping ,但传递给会被视为 URL 而不是 IP 地址——可能存在(但遗憾的是不存在)。换句话说,它会尝试对顶级域 上的域上的子域进行 ping 。但是,由于不是有效的 TLD(如、及其伙伴),因此连接在第一步就失败了。8.16.24.32
010.020.030.080
ping
foo.bar.baz.com
010
020
030
080
080
.com
.net
090.010.010.010
当无效字符位于不同的八位字节中时,也会发生同样的事情。同样, 0xf.0xf.0xf.0xf
ping 15.15.15.15
,但0xh1.0x1.0xg0.0f
失败。
哦,好吧,我猜这就是你不熟练掌握多种数字基数所得到的后果。
确保始终使用 4 点四组(“40q”?“quady-quad”?“cutie-q”?)地址可能更容易、更安全。
所以继续前进学习一些数字基数。你将能够在聚会上炫耀并成为聚会的焦点,正如人们所说,人分为十种类型:懂二进制的人和不懂二进制的人。
我们甚至不要思考关于 IPv6 地址;我认为它们是 111 个印章之一!!!
答案2
答案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