Вопрос Почему pinging 192.168.072 (всего 2 точки) возвращает ответ от 192.168.0.58?


Я ошибочно пропустил точку с 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 (в моей первоначальной ошибке).


Этот вопрос был Суперпользовательский вопрос недели,
Прочтите запись в блоге для более подробной информации или вносить свой вклад в блог сам


370
2017-10-12 10:26


происхождения


Соответствующий:  blog.superuser.com/2012/02/10/wtfriday-http2915189091 - Tom Wijsman
Интересно, что то же самое происходит и с Linux: ping 192.168.072 печать PING 192.168.072 (192.168.0.58) 56(84) bytes of data.[...]. - Mechanical snail
еще более случайным является то, что у вас была машина на 192.168.0.58 чтобы получить ответ. Каковы шансы на это? - KronoS
@KronoS это на самом деле не так странно, если вы находитесь в школе или сети компании. Некоторые DHCP-серверы будут получать адреса в порядке возрастания, и большинство из них будут использоваться. - Taum
192.168.0.58 это время для меня .. могут ли все запросы ping каким-то образом выбить сервер ?! - iamserious


ответы:


Все чрезмерно усложняют его с помощью 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-адрес можно разбить на четыре части («dotted-quad») так: 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).

Есть несколько краевых случаев, таких как предоставление более четырех частей, кажется, не работает (например, pinging google.comIP не будет работать ни для 0.74.125.226.4 или 74.125.226.4.0).

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


Таким образом, существует множество способов представления IP-адреса (IPv4). Вы можете использовать формат flat или dotted-quad (или dotted-triple, dotted-double или even dotted-single), и для каждого из них вы можете использовать (или даже смешивать и сопоставлять) десятичные, восьмеричные и шестнадцатеричные. Например, вы можете пинговать 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), так что вы на самом деле pinging 192.168.0.072, Кроме того, поскольку у вас есть начальный ноль на последней части, он рассматривается как восьмеричный, который в десятичном значении равен 58.

Тайна решена.


Обратите внимание, что в то время как Windows ping команда допускает такое широкое разнообразие форматов ввода и интерпретирует нестандартные форматы в видимых случаях, что не обязательно означает, что вы можете использовать такие форматы везде. Некоторые программы могут заставить вас предоставить все четыре части пунктирного квадратика, другие могут не допускать смешивания и сопоставления десятичных и восьмеричных и т. Д.

Кроме того, адреса IPv6 еще более усложняют логику синтаксического анализа и приемлемость входного формата.


добавление:

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

(Как человек, у которого были многочисленные аневризмы и сердечные приступы, пытающиеся написать якобы «простой» код для размещения экспоненциально взрывающегося количества перестановок значений данных, я ценю, что он, кажется, правильно обрабатывает все входные вариации, в этом случае, не менее 31+32+33+34знак равно120 вариации.)

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

То же самое происходит с 090.010.010.010 где недопустимый символ находится в другом октете. Точно так же, 0xf.0xf.0xf.0xf пинги 15.15.15.15, но 0xh1.0x1.0xg0.0f выходит из строя.

О, хорошо, я думаю, это то, что вы получаете за то, что не свободно владеете множеством оснований.

Вероятно, проще и безопаснее просто всегда использовать четырехточечные («40q»? «Quaddy-quad»? «Cutie-q»?) Адреса.

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

Давай даже думать о адресах IPv6; Я думаю, что они одна из 111 тюленей !!!


565
2017-10-12 17:06



Усложнять? Экспериментация может быть очень полезной, и в этом случае получился хороший ответ; но без теории или документации или стандартов, вы можете пропустить критический фактор и не знать этого. Или вы можете определить, как работает одна конкретная версия, и ошибаться около 90% реализаций там. Или вы можете придумать правила, объясняющие результаты ваших экспериментов, но более сложные, чем предполагаемые правила. В этом случае я считаю, что правила документирования (для inet_aton()) проще в одном отношении - нет условностей для «под / над 255». - LarsH
Эй смотри! Появляется «научная» часть Информатики! (гипотеза, эксперимент, проверка) - Izkata
@LarsH, это моя точка зрения, что ping команда (по крайней мере, в Windows) похожа на многие из программ Microsoft (особенно пресловутый) IE. Он пытается быть слишком прощающим и принимать все, что вы бросаете на него, и пытается его интерпретировать. Да, есть официальный документ о форматах IP-адресов, но это не вопрос об ISO и RFC, это практично, Я что-то сделал, и это странно вопрос, на который можно ответить, не прибегая к (по общему признанию, длительным, сухим, скучным техническим спецификациям), хотя связь с ними в случае, если ОР хочет их читать, тоже хороша. - Synetech
0-префиксный восьмеричный синтаксический анализ должен быть полностью оставлен, за исключением chmod, Вот и все. Это единственное исключение для восьмеричного разрешения. Период. - James Dunne
это полезно для преобразования RGB HEX в DEC. лол ~ C:\>ping 0xffffcc  Pinging 0.255.255.204 with 32 bytes of data: - wilson


Для этого есть две причины:

Во-первых, префикс '0' указывает на восьмеричный номер. Так как oct (072) = dec (58), 192.168.072 = 192.168.58.

Во-вторых, второе-последнее 0 можно отбросить с IP-адресов в виде стенография, 127.0.1 интерпретируется как 127.0.0.1, а в вашем случае 192.168.58 интерпретируется как 192.168.0.58.


147
2017-10-12 10:39



Он не группирует нули. Он фактически обрабатывает каждую точку как разделитель, соответствующий границе следующего байта. Таким образом, IP-адреса 2130706433 и 127.0.0.1 являются одинаковыми адресами. - Serge
имеет ли обозначение x.x.x.x для 32-битовых чисел имя? Он может использоваться / полезен в других доменах, но я не могу его использовать. Edit: nevermind, это десятиточечная нотация - Guillaume86
более точно это четырехточечная пунктирная нотация в случае IP-адреса - Guillaume86
Знаменитый ведущий ноль поразил еще раз! - Luc M
теперь это реальный ответ! - l--''''''---------''''''''''''


В дополнение к важному вопросу @ 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 соответствует шаблону a.b.c, поэтому 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) допускают более общие   обозначение чисел и точек (шестнадцатеричные и восьмеричные форматы и   форматы, которые не требуют четкого написания всех четырех байтов).


97
2017-10-12 15:33



Это, безусловно, лучший ответ ИМХО. - Josh
В Windows вы ищете inet_addr в Уинсоке. - user7116


Вы также должны учитывать, что 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

25
2017-10-12 13:57



«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 OP будет интерпретироваться как 192.168.58.0 вместо 192.168.0.58. - LarsH
Что немного вводит в заблуждение, так это то, что адрес имеет 0, имеет 3-ю цифру. Рассмотрим этот адрес 192.168.1.56. Трехзначная форма будет 192.168.312. Поскольку 1 * 256 ^ 1 + 56 * 256 ^ 0 равно 312 - vesquam
Точки служат только для определения того, какие числа должны быть умножены на мощность 256. Парсер ищет первую точку и умножает число до 2566. Повторите для 2-й и 3-й точек, но соответственно 256 ^ 2 и 256 ^ 1. Затем он добавляет все результаты вместе (некоторые impl. Могут содержать текущую сумму вместо этого, хотя результат тот же). Если какая-либо из этих точек отсутствует, она просто не выполняет умножение и просто добавляет конечный номер к общей сумме. Вот почему 1.2.3. приводит к ошибке, потому что синтаксический анализатор не может найти последнее число, добавляемое к сумме. - Justin ᚅᚔᚈᚄᚒᚔ