Чому pinging 192.168.072 (лише 2 крапки) повертає відповідь з 192.168.0.58?


379

Я помилково пропустив крапку IP-адреси та ввів 192.168.072.
На моє здивування я підключився до машини в192.168.0.58

Якщо я пінг, 192.168.072я отримую відповіді 192.168.0.58.

Чому це?


Я на ПК з Windows в домені Windows.


Якщо я пінг, 192.168.72я отримую відповідь 192.168.0.72, тому здається, що 0в 072(за моєю первісною помилкою) важливо.


Це питання було питанням суперкористувача тижня .
Прочитайте запис у блозі для отримання більш детальної інформації або допишіть до себе



2
Цікаво, що саме те саме відбувається і в Linux: ping 192.168.072друкує PING 192.168.072 (192.168.0.58) 56(84) bytes of data.[...].
— Механічний равлик

9
що ще більш випадково - це те, що у вас була машина, 192.168.0.58щоб отримати відповідь. Які шанси на це?
— Джеймс Мерц

3
@KronoS це насправді не так дивно, якщо ти знаходишся в школі чи мережі компаній. Деякі сервери DHCP надаватимуть адреси в порядку більшого порядку, і більшість з них буде використовуватися.
— Таум

5
192.168.0.58настає час для мене .. чи можуть усі запити ping якось вибити сервер ?!
— примхливий

Відповіді:


570

Усі надмірно ускладнюють це 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).

Є кілька крайових випадків, таких як надання більш ніж чотирьох частин, схоже, не працює (наприклад, google.comIP-адреса Pinging не буде працювати ні для одного, 0.74.125.226.4ні для 74.125.226.4.0).

Ви також можете використовувати шістнадцяткові позначення як у пунктирній, так і у плоскій формі, але потрібно відформатувати їх, попередньо очікуючи 0xна кожен октет.


Отже, існує безліч способів представити IP-адресу (IPv4). Ви можете використовувати плоский або крапковий (або пунктирний-потрійний, пунктирний-подвійний або навіть крапковий-одинарний) формат, і для кожного з них ви можете використовувати (або навіть змішувати та зіставляти) десятковий, вісімковий і шістнадцятковий. Наприклад, ви можете ввести пінг google.comтакими способами:

  • google.com  (Доменне ім'я)
  • 74.125.226.4  (пунктир)
  • 1249763844  (плоска десяткова)
  • 0112.0175.0342.0004  (пунктир)
  • 011237361004  (плоский восьмикутник)
  • 0x4A.0x7D.0xE2.0x04  (пунктир)
  • 0x4A7DE204  (плоский шестигранник)
  • 74.0175.0xe2.4  (ಠ_ಠ)

(Слава богу, що підтримка бінарних нотацій не додана!)


Застосування :

У вашому випадку pinging 192.168.072використовує третій формат у наведеній вище таблиці ( A.B.0.C), тож ви насправді пінгінгу 192.168.0.072. Далі, оскільки у вас є попередній нуль на останній частині, він трактується як вісімковий, який у десятковій частині дорівнює 58.

Таємниця вирішена.


Зауважте, що, хоча команда Windows pingдозволяє настільки широкий спектр форматів для введення та інтерпретує нестандартні формати у видимий спосіб, це не обов'язково означає, що ви можете використовувати такі формати скрізь. Деякі програми можуть змусити вас надати всі чотири частини крапки з пунктиром, інші можуть не дозволяти змішувати та співставляти десятковий і восьмеричний тощо.

Також адреси IPv6 ще більше ускладнюють логіку розбору та прийнятність формату введення.


Додаток :

syss вказував, що якщо ви використовуєте недійсний символ в одному з чисел (наприклад, 8або 9при використанні восьмеричного, gв шістнадцятковому режимі тощо), то pingце досить розумно, щоб розпізнати це і інтерпретувати його як рядок (-al? -ic?) URL, а не як числова IP-адреса.

(Оскільки той, хто мав численні аневризми та серцеві напади, намагаючись написати нібито «простий» код для розміщення експоненціально вибухової кількості перестановок значень даних, я розумію, що це, здається, - правильно обробляє всі вхідні зміни; в цьому випадку, принаймні 3 1 +3 2 +3 3 +3 4 = 120 варіантів.)

Отже, визначаючи, як 010.020.030.040буде ping, 8.16.24.32як очікувалося, перехід 010.020.030.080до pingбуде розглядатися як URL-адреса, а не IP-адреса, як, наприклад, foo.bar.baz.comяка (але, на жаль, не існує). Іншими словами, він намагається пінг піддомену 010на піддомен 020в домені 030на домені верхнього рівня 080. Однак, оскільки 080не є дійсним TLD (як .com, .netі їхні приятелі), з'єднання не вдається відразу на першому кроці.

Те саме відбувається з тим, 090.010.010.010де недійсний символ знаходиться в іншому октеті. Так само 0xf.0xf.0xf.0xfпінг 15.15.15.15, але 0xh1.0x1.0xg0.0fне вдається.

Ну добре, я думаю, що це ви отримуєте за те, що не володієте кількома базами даних.

Напевно, простіше і безпечніше просто переконатися, що завжди використовувати 4-крапкові ("40q"? "Quaddy-quad"? "Cutie-q"?) Адреси.

Тому продовжуйте вивчати основи чисел . Ви зможете продемонструвати себе і прожити життя партій, і, як кажуть, є 10 типів людей: тих, хто знає бінарне, і тих, хто цього не робить.

Давайте навіть не думати про IPv6 адреси; Я думаю, що вони одна з 111 печаток !!!


39
Надмірне ускладнення? Експериментація може бути дуже корисною і в цьому випадку дала хорошу відповідь; але без теорії чи документації чи стандартів ви можете пропустити критичний фактор і не знати цього. Або ви можете визначити, як працює одна конкретна версія, і помилитесь приблизно в 90% реалізацій там. Або ви можете придумати правила, які пояснюють результати ваших експериментів, але вони складніші за передбачені правила. У цьому випадку я думаю, що правила документації (для inet_aton()) простіші в одному відношенні - ніяких умов для "під / понад 255".
— LarsH

71
Гей, дивись! "Наукова" частина Інформатики робить вигляд! (гіпотезувати, експериментувати, перевірити)
— Ізката

13
@LarsH, але це мій погляд, що pingкоманда (принаймні, в Windows) подібна до багатьох програм Microsoft (особливо горезвісного) IE. Він намагається бути надто прощальним і приймати все, що ви кинете на нього, і намагається його інтерпретувати. Так, є офіційний документ про формати IP-адреси, але це не питання про ISO та RFC, це практично, я щось зробив і на це дивне питання, на яке можна відповісти, не вдаючись до (правда, довгий, сухий, нудний) технічні умови) - хоча посилання на них, якщо ОП хоче їх прочитати, також добре.
— Synetech

6
0-префіксальний восьмеричний аналіз слід повністю відмовитися, окрім chmod. Це воно. Це єдиний виняток для дозволеного восьмерика. Період.
— Джеймс Данн

6
це корисно для перетворення REX HEX в DEC. lol ~C:\>ping 0xffffcc Pinging 0.255.255.204 with 32 bytes of data:
— wilson

147

Для цього є дві причини:

По-перше, префікс '0' вказує восьмеричне число. Оскільки oct (072) = dec (58), 192.168.072 = 192.168.58.

По-друге, "0 до останнього" 0 можна скинути з IP-адреси як скорочення . 127.0.1 інтерпретується як 127.0.0.1, а у вашому випадку 192.168.58 інтерпретується як 192.168.0.58.


7
Він не групує нулі. Він фактично розглядає кожну крапку як роздільник, відповідний наступній границі байтів. Таким чином, IP-адреси 2130706433 та 127.0.0.1 - це однакові адреси.
— Серж

2
точніше, це чотиризначні позначення у випадку IP-адреси
— Guillaume86,

4
Знаменитий ведучий нуль потрапив ще раз!
— Люк М

2
тепер це справжня відповідь!
— l --'''''--------- '' '' '' '' ''

2
Ця відповідь є невірною та оманливою. Випадання 0 в 1.0.2.3 (1.2.3) дає іншу IP-адресу (1.2.0.3).
— sch

101

Окрім важливого моменту @ neu242 щодо восьмеричного позначення та зауваження, що IP-адреси можна скоротити, інший критичний фрагмент - це те, як інтерпретуються скорочені IP-адреси.

Можна наївно здогадуватися, що якщо деякі з чотирьох чисел відсутні, аналізатор додасть заповнені нулем байти в кінець (або на початок) послідовності байтів. Але це не відповідає поведінці, про яку повідомляє ОП: 192.168.072 було розбито на 192.168. 0 .58, а не як 192.168.58. 0 , ні 0 .192.168.58.

Мабуть, для Windows та Linux ping (версія, яку ви пробували, та ті, яку я спробував) використовуйте щось еквівалентне inet_aton () для розбору аргументу IP-адреси. Сторінка man для 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 (включаючи пінг) , які я знайшов використовує inet_pton () , а не inet_aton () для розбору IP - адреса аргументу. Сторінка man для inet_pton () говорить:

На відміну від inet_aton (3) та inet_addr (3), inet_pton () підтримує IPv6 адреси. З іншого боку, inet_pton () приймає лише адреси IPv4 у крапково-десятковій нотації, тоді як inet_aton (3) та inet_addr (3) дозволяють більш загальні позначення чисел і крапок (шістнадцятковий і восьмеричний формати чисел та формати, які не містять " t вимагати, щоб усі чотири байти були чітко записані).


12
Це, безумовно, найкраща відповідь ІМХО.
— Джош

У Windows, яку ви шукаєте inet_addrв Winsock.
— користувач7116

24

Ви також повинні врахувати, що 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

1
"192.168.56 буде 192.168.0.56, тому що 0 * 256 ^ 1 + 58 * 256 ^ 0 = 58" Ви впевнені? Ви очікували, що 168 у першому випадку буде помножено на 256 ^ 1, а в другому - 256 ^ 2. Аналогічно 192 було б помножено на 256 ^ 2 проти 256 ^ 3. Тож 192.168.56 міг би = = 192.168.0.56, лише якщо існують додаткові правила, такі як падіння нулів.
— LarsH

@LarsH, я думаю, що тут йдеться про те, що це базується зліва направо, на відміну від "нормального" підрахунку, де ми базуємо все з місця 1. Отже, перша крапка призводить до того, що ліворуч від неї множиться на 256 ^ 3, друга на 256 ^ 2, третя на 256. Якщо зліва від неї немає точки, то вона додається без множення на 256 ^ н. Так 1.2.3. (1.2.3.0) був би іншим, ніж 1.2.3 (1.2.0.3), якщо я правильно розумію.
— iX3

@ iX3: якби це було так, то "192.168.56 буде 192.168.0.56" було б невірно, оскільки в першому випадку 56 було б помножено на 256 ^ 1, тоді як у другому випадку 56 було б помножено лише y 256 ^ 0. І 192.168.072 ОП трактуватиметься як 192.168.58.0 замість 192.168.0.58.
— LarsH

Трохи оманливим є той факт, що адреса 0 має 3-ю цифру. Розглянемо цю адресу 192.168.1.56 3-цифрова форма буде 192.168.312 Тому, що 1 * 256 ^ 1 + 56 * 256 ^ 0 - 312
— vesquam

1
Точки служать лише для того, щоб окреслити, які числа слід помножити на потужність 256. Парсер шукає першу крапку і помножує число перед нею на 256 ^ 3. Повторіть для 2-ї та 3-ї крапки, але відповідно на 256 ^ 2 і 256 ^ 1 відповідно. Потім він додає всі результати разом (деякі імпл. Можуть замість цього тримати загальний результат, хоча результат той самий). Якщо будь-яка з цих точок відсутня, вона просто не робить множення і просто додає кінцеве число до поточного загального числа. Ось чому це 1.2.3.призводить до помилки, оскільки аналізатор не може знайти останнє число, яке слід додати до загальної суми.
— Джастін ᚅᚔᚈᚄᚒᚔ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.