題 帶有和不帶前導零的IP地址是否相同?


我有一個安全系統,網絡設置只允許三位數的IP地址。我無法設置它 192.168.2.100相反,我必須使用 192.168.002.100

這兩個IP地址是不同的嗎?我是否需要將路由器的LAN設置為全部 192.168.xxx.xxx 為了使其正常工作?我找不到任何關於此的可靠信息。


83
2017-12-28 02:45


起源


接下來的答案應該是192.168.020.100 不 與192.168.20.100相同,但它 可以 如果您的系統只允許以這種方式輸入IP,那麼就是相同的(當使用上下箭頭逐位輸入IP時,我已經看到了複印機)。 - 即使可以“正常”鍵盤輸入,你的系統也有這種怪癖(即你 能夠 技術輸入 192.168.2.100,但它抱怨),然後我建議你與供應商談談(如果輸入驗證是如此糟糕,安全系統如何值得信賴?) - Hagen von Eitzen
這確實是一個非常奇怪的驗證。正如@Hagen暗示的那樣,我會切換安全系統。 - Lightness Races in Orbit
這也可以是特定於軟件的。它們無論有沒有領先都有效 0s,但我遇到了一些不支持每個八位字節中沒有3位數的IP地址的應用程序。 - ps2goat
所有IP(v4)地址實際上只是以很好的方式表示的32位。如果 192.168.002.100 是你的工具代表的方式 0xc0a80264/3232236132 /192.168.2.100那就是同樣的事情。 - Tim S.
你能接受另一個答案嗎?你接受的那個是非常錯誤的(或至少是不完整的)並有11個downvotes。 - Arjan


答案:


假設您使用的所有軟件都正確使用點十進制和子網,是的,它們是相同的。

例如,192.168.0.1只是點二進制值11000000.10101000.00000000.00000001的友好點十進製表示法。

無論您鍵入192.168.0.1還是192.168.000.001,它們都等於11000000.10101000.00000000.00000001


64
2017-12-28 02:56



點也是為了方便;真正的IP是11000000101010000000000000000001 - cpast
@cpast或十六進制數: C0A80001 - jfs
或者作為八進制數(從0開始,有或沒有點),例如ping 0300.0250.2.0144 for 192.168.2.100 - Sergey
或者作為十進制數 3232235521 - oldmud0
正如@GreenstoneWalker的回答指出的那樣,許多程序都不會認為它們是相同的;帶前導零的數字(不包含數字8或9)將被理解為八進制數字;因此010.000.001.063將被解釋為“8.0.1.51”(八進制010 =十進制8;八進制063 =十進制51)而不是“10.0.1.63”! - Doktor J


這取決於工具。

在大多數情況下,兩者將是相同的,但並非總是如此。

例如,如果您使用以零開頭的3位數字(或者以零開頭的兩位數字,感謝@ Dietrich-Epp),那麼ping將假設數字為八進制。

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users>ping 011.012.013.014

Pinging 9.10.11.12 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 9.10.11.12:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

99
2017-12-28 04:08



不是ping,而是它使用的基礎例程 inet_addr() - cde
它也發生在OSX上。 - Johann Philipp Strathausen
這不是因為它有三位數,而是因為數字有一個前導零。您可以通過嘗試ping 09.09.09.09來測試這一點,這不起作用,因為9在八進制中無效。 - Dietrich Epp


它取決於任何給定程序用於解析給定地址的工具或函數。 Microsoft和Linux以及其他操作系統都使用 POSIX 兼容 inet_addr() 解析地址的例程。

許多TCP / IP程序(如Ping和FTP)使用inet_addr()套接字函數將IP地址字符串轉換為4字節地址。此函數接受標準十進制,八進制和十六進製表示法的IP地址。
  Microsoft KB115388 Ping和FTP使用前導零作為八進制解析IP地址

inet_addr()函數將Internet主機地址cp從IPv4數字和點符號轉換為網絡字節順序的二進制數據。

在所有上述形式中,虛線地址的組件可以用十進制,八進制(帶前導0)或十六進制指定,前導0X)。任何這些形式的地址統稱為 IPv4的 數字和點符號。使用正好四個十進制數的表單稱為IPv4點分十進製表示法(或者有時稱為IPv4點四符號表示法)。
inet_addr(3):Internet地址更改例程 - Linux手冊頁

因此,您的特定係統可能需要為每個八位字節使用三位十進製表示法,但這不是通用的,應注意確保輸入正確的IP地址。

當然,只有每種類型的有效數字才有效。超出範圍八進制,十六進製或十進制數也將失敗或導致問題。八進制088,十六進制0xGG或十進制280都是無效示例。


35
2017-12-28 17:42



基礎功能+1。要添加,如果有效字節(例如.88)為零填充,則此函數將導致IP解析失敗,因為8不是八進制中的有效數字。 - March Ho
在Windows XP(以及之前)中,函數將接受無效的八進制數,並仍嘗試轉換它們。這可能導致非常明顯的行為。從Vista開始,無效數字被視為域名,Windows將嘗試對這些域名進行DNS查找。這也是非常奇怪的行為,但這至少不會導致任何問題。 - Tonny
@tonny那是因為POSIX inet_addr()為無效值返回-1,它循環到255.如Linux手冊頁中所述,較新的例程具有更好的錯誤處理能力。 - cde
@cde我從來沒有費心去深入研究inet_addr()的機制。你的話我記住了 :-) - Tonny


軌道中的輕盈競賽 和其他人指出,

INET(3) 手冊頁 介紹 inet_addr 和 inet_aton,用於將“IPv4數字和點符號轉換為二進制形式”的標準函數。它說

...虛線地址的組成部分可以十進制指定, 八進制(前導0)或十六進制,帶前導0X)。

從技術上講, 沒有,帶有前導零的IP地址(總是)與沒有前導零的IP地址相同。但是,在你的情況下, 192.168.2.100 和 192.168.002.100 是相同的,因為 002 == 2

任何用戶界面都要求每個組件長度正好為三個字符,並且前導零的位置不正確。


12
2017-12-30 08:18



在某些設備上需要“領先零”的想法似乎沒有爭議;稱“錯誤要求”/“破碎”的基礎是什麼?因為它違反了INET(3)/ inet_addr / inet_aton?需要這種零的實現可能使用其他可以正常通信的代碼,因此不會被“破壞”。 (我見過打印機這樣做。)是否有基礎可以說INET(3)手冊頁比其他官方文檔(如RFC和其他引用的文檔)更“權利”/更具權威性。 該草案文件? - TOOGAM


一些實現認為具有前導零的八位字節是十進制的,其他實現認為它們是八進制的。只要八位位組在0到7的範圍內,這就沒有區別。所以例如會 192.168.002.100 被解釋為 192.168.2.100 在兩個實現中。

但是如果你要輸入一個地址 192.168.010.100 它可以被解釋為 192.168.10.100 要么 192.168.8.100 取決於實施。實現也不可能存在,這會將前導零視為語法錯誤。此外,在某些情況下,軟件可能會因為某種原因而必須使用規範表示。出於所有這些原因,我建議在寫入IP地址時避免使用前導零。

如果您編寫需要解析IP地址的軟件,我建議接受前導零,但在發生時將警告輸出到適當的位置。

稍微相關的是允許您使用點分錶示法的組件少於四個的實現。當少於四個組件時,最後一個組件具有多於8位,而較早的組件恰好具有8位。例如 192.168.612 實際上是一種有效的寫作方式 192.168.2.100。但不建議再次使用該表示法。


5
2017-12-30 18:54





只是一點提示: 在某些情況下,在IP地址中使用零前綴非常重要。一個例子是Apache .htaccess拒絕規則。

如果你使用類似的東西

deny from 11.22.33.22

Apache非常愚蠢,也會阻止來自以下IP的訪問:

111.22.33.22

11.22.33.221

211.22.33.221

一般來說,任何IP地址 包括 11.22.33.22

因此,為了確保您不會阻止任何您不想阻止的IP,您應該使用:

deny from 011.022.033.022

確保Apache僅阻止從11.22.33.22 IP地址訪問。


0
2018-01-18 06:27



有趣。你能為此提供參考嗎? - Scott
在發現許多訪問者因未使用前導零被阻止後,參考是個人經驗和許多試驗和錯誤。避免錯誤禁止的另一種方法是使用CIDR格式的IP。例如,11.22.33.22 / 32而不僅僅是11.22.33.22 - Nick Gar


小心這個。它 應該 是相同的,但它是
我無法找到這方面的解釋,但我可以肯定地說,在Windows和Linux上,有和沒有前導零的IP地址是不一樣的!也許這與從十六進製或二進制等其他格式轉換有關。

根據我對Windows和Linux的經驗,它不是工具依賴,但是它依賴於它似乎是因為即時通訊運行在使用像10.08.03.100這樣的ips的一些問題:

  • 注意:找不到“10.08.0.1”和10.09.0.1
  • 注意:“10.010.0.1”被解析為10.8.0.1

LINUX / debian7 / 8: 使用“ping”和“snmpget”工具獲得相同的結果

user@test:~$ ping 10.7.0.1
PING 10.7.0.1 (10.7.0.1) 56(84) bytes of data.
^C
--- 10.7.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

user@test:~$ ping 10.07.0.1
PING 10.07.0.1 (10.7.0.1) 56(84) bytes of data.
^C
--- 10.07.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

user@test:~$ ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
^C
--- 10.8.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

user@test:~$ ping 10.08.0.1
**ping: unknown host 10.08.0.1**
user@test:~$ ping 10.9.0.1
PING 10.9.0.1 (10.9.0.1) 56(84) bytes of data.
^C
--- 10.9.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

user@test:~$ ping 10.09.0.1
ping: unknown host 10.09.0.1
user@test:~$ ping 10.10.0.1
PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data.
^C
--- 10.10.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

user@test:~$ ping 10.010.0.1
PING 10.010.0.1 (10.8.0.1) 56(84) bytes of data.
^C
--- 10.010.0.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1001ms

的windows7 / 8/10: 使用“ping”和“telnet”工具獲得相同的結果

(抱歉,我手邊沒有英文窗口,錯誤告訴主機無法找到)

C:\Users\user>ping 10.7.0.1

Ping wird ausgeführt für 10.7.0.1 mit 32 Bytes Daten:
STRG-C
^C
C:\Users\user>ping 10.07.0.1

Ping wird ausgeführt für 10.7.0.1 mit 32 Bytes Daten:
STRG-C
^C
C:\Users\user>ping 10.8.0.1

Ping wird ausgeführt für 10.8.0.1 mit 32 Bytes Daten:
STRG-C
^C
C:\Users\user>ping 10.08.0.1
Ping-Anforderung konnte Host "10.08.0.1" nicht finden. Überprüfen Sie den Namen,

C:\Users\user>ping 10.9.0.1

Ping wird ausgeführt für 10.9.0.1 mit 32 Bytes Daten:
STRG-C
^C
C:\Users\user>ping 10.09.0.1
Ping-Anforderung konnte Host "10.09.0.1" nicht finden. Überprüfen Sie den Namen,

C:\Users\user>ping 10.10.0.1

Ping wird ausgeführt für 10.10.0.1 mit 32 Bytes Daten:
STRG-C
^C
C:\Users\user>ping 10.010.0.1

Ping wird ausgeführt für 10.8.0.1 mit 32 Bytes Daten:
STRG-C
^C

0
2017-07-15 15:30



前導零通常表示八進制。實際上,八進制010是十進制8,而08和09是無效的八進制數。所以是的,AthomSfere的(當前)接受的答案是錯誤的(或者至少是不完整的)。請參閱其評論和其他一些答案。 - Arjan
呃,處理10.010.0.1非常糟糕。在Microsoft Windows中,ping 10.070.0.1被視為10.56.0.1,10.080.0.1發出即時錯誤,“Ping請求找不到主機10.080.0.1。請檢查名稱,然後重試。” - TOOGAM
是的,@ TOOGAM,八進制070是十進制56.八進制080不是有效數字。 - Arjan


兩個IP地址不同。

然而:

  • 人們通常認為它們是相同的。
  • 有些軟件會認為它們是相同的。
  • 在某些平台上,某些軟件會將它們視為不同。

如果這聽起來令人困惑,那是因為沒有標準來管理IP地址的編寫方式,因此歷史上不同點和不同平台上的不同程序員對於應該做什麼都有不同的想法。

IP地址實際上是二進制的,人們傾向於使用點分十進製表示法來表示IP地址。軟件可以接受各種數字基礎(即十進制,八進制,十六進制),並根據您編寫的方式以各種方式解釋事物。你如何寫它可以告訴軟件你寫的是什麼基礎。

我勸告你: 不要使用前導零 如果你的意思是使用點分十進製表示法。某些軟件會認為該標誌表示您輸入的是八進制數。如果您要輸入十進制數字,則無法獲得預期的結果。

我問了一個 類似的問題 並得到了一些很好的回复,所以如果你想閱讀RFC,那裡有很好的信息。


-4
2017-07-10 14:20





它應該以任何方式工作。您甚至可以ping三位數字,計算機將了解IP地址。

編輯:windows會把它讀成八進制,這只適用於Linux。


-6
2017-12-28 02:46



這是真的。眾所周知,點狀十進制格式實際上僅適用於人類。網絡上的設備不使用此IP地址表示。 - Patrick Seymour
@Brock Vond:是的,除了我認為你意外地改變了186和168。 - Patrick Seymour
使用帶有3位數字的ping可能不起作用。它可能會將它們視為八進制。 - Greenstone Walker
@LightnessRacesinOrbit實際上,即使你對它們進行零填充,給定的例子也會起作用,至少在Windows和Debian中是這樣(我沒有Mac)。如果數字為零填充,並且零填充數大於7(因為八進制和十進制將相同),則僅出現錯誤/特徵。如果您嘗試輸入零填充的有效十進制地址(例如012.034.056.078),它仍將嘗試將其解析為八進制,從而導致ping函數失敗。 - March Ho
@MarchHo:是的,這就是我們所說的。 - Lightness Races in Orbit