Por que o ping 192.168.072 (apenas 2 pontos) retorna uma resposta do 192.168.0.58?

378

Por engano, perdi o ponto de um endereço IP e digitei 192.168.072.
Para minha surpresa, conectei-me a uma máquina em192.168.0.58

Se eu fizer ping 192.168.072, recebo respostas de 192.168.0.58.

Por que é isso?


Estou em um PC com Windows em um domínio do Windows.


Se eu fizer ping 192.168.72, recebo uma resposta de 192.168.0.72, então parece que o 0in 072(no meu erro original) é significativo.


Esta pergunta foi uma pergunta da semana para superusuários .
Leia a entrada do blog para obter mais detalhes ou contribua com o blog você mesmo

George Duckett
fonte
2
Curiosamente, exatamente o mesmo acontece no Linux: ping 192.168.072impressões PING 192.168.072 (192.168.0.58) 56(84) bytes of data.[...].
Caracol mecânico
9
o que é ainda mais aleatório é que você tinha uma máquina 192.168.0.58para obter uma resposta. Quais são as chances disso?
James Mertz 12/12
3
@KronoS na verdade não é tão estranho se você estiver em uma escola ou rede de empresas. Alguns servidores DHCP fornecerão endereços em ordem crescente e a maioria deles será usada.
Taum
5
192.168.0.58está atingindo o tempo limite para mim .. todos os pedidos de ping podem de alguma forma nocautear o servidor ?!
iamserious

Respostas:

569

Todo mundo está complicando demais com RFCs, classes de IP e outras coisas. Simplesmente execute alguns testes para ver como o pingcomando analisa a entrada IP pelo usuário (remoção estranha de palha):

> 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:

Como você pode ver, o pingcomando (no Windows) permite usar diferentes formatos de endereço IP. Um endereço IPv4 pode ser dividido em quatro partes (“dotted-quad”) da seguinte maneira: A.B.C.De o pingcomando permite que você deixe de fora alguns, preenchendo o padrão da 0seguinte maneira:

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

Se você fornecer apenas uma peça, se estiver abaixo de 255 (o máximo para um octeto), ela será tratada como um octeto como acima, mas se for maior que 255, será convertida e rolada para o próximo campo (ou seja mod 256).

Existem alguns casos extremos, como fornecer mais de quatro partes não parece funcionar (por exemplo, google.como IP do ping não funcionará para um 0.74.125.226.4ou outro 74.125.226.4.0).

Você também pode usar a notação hexadecimal na forma de quad-dotted e flat, mas deve formatá-la pré-pendente 0xpara cada octeto.


Portanto, existem várias maneiras de representar um endereço IP (IPv4). Você pode usar o formato plano ou quadriculado (ou pontilhado triplo, pontilhado duplo ou mesmo pontilhado único) e, para cada um, pode usar (ou até misturar e combinar) decimal, octal e hexadecimal. Por exemplo, você pode executar ping google.comdas seguintes maneiras:

  • google.com  (nome do domínio)
  • 74.125.226.4  (decimal pontilhado)
  • 1249763844  (decimal simples)
  • 0112.0175.0342.0004  (octal pontilhado)
  • 011237361004  (octal plano)
  • 0x4A.0x7D.0xE2.0x04  (hexadecimal pontilhado)
  • 0x4A7DE204  (hexágono plano)
  • 74.0175.0xe2.4  (ಠ_ಠ)

(Graças a Deus que o suporte à notação binária não foi adicionado!)


Aplicação :

No seu caso, o ping 192.168.072usa o terceiro formato na tabela acima ( A.B.0.C), então você está realmente pingando 192.168.0.072. Além disso, como você tem um zero à esquerda na última parte, ele é tratado como octal, que em decimal é 58.

Mistério resolvido.


Observe que, embora o pingcomando do Windows permita uma variedade tão grande de formatos para a entrada e interprete formatos fora do padrão da maneira vista, isso não significa necessariamente que você possa usar esses formatos em qualquer lugar. Alguns programas podem forçar você a fornecer todas as quatro partes de um quadriculado pontilhado, outros podem não permitir a mistura e correspondência de decimal e octal, e assim por diante.

Além disso, os endereços IPv6 complicam ainda mais a aceitabilidade da lógica de análise e do formato de entrada.


Adendo :

syss apontou que, se você usar um caractere inválido em um dos números (por exemplo, um 8ou 9ao usar octal, a gno modo hexadecimal etc.), então pingé inteligente o suficiente para reconhecer isso e interpretá-lo como uma string (-al? URL em vez de como um endereço IP numérico.

(Como alguém que teve vários aneurismas e ataques cardíacos tentando escrever código supostamente "simples" para acomodar o número exponencialmente explosivo de permutações de valores de dados, eu aprecio que ele parece processar corretamente todas as variações de entrada; caso, pelo menos 3 1 +3 2 +3 3 +3 4 = 120 variações.)

Portanto, ao especificar 010.020.030.040o ping 8.16.24.32como esperado, a passagem 010.020.030.080para pingserá tratada como uma URL em vez de um endereço IP - como o foo.bar.baz.comque poderia (mas infelizmente não existe). Em outras palavras, ele tenta executar ping no subdomínio 010no subdomínio 020no domínio 030no domínio de nível superior 080. No entanto, como 080não é um TLD válido (como .com, .nete seus amigos), a conexão falha logo na primeira etapa.

O mesmo acontece com 090.010.010.010o caractere inválido em um octeto diferente. Da mesma forma, 0xf.0xf.0xf.0xfpings 15.15.15.15, mas 0xh1.0x1.0xg0.0ffalha.

Bem, acho que é isso que você ganha por não ser fluente em várias bases de números.

Provavelmente é mais fácil e seguro garantir sempre o uso de endereços com quatro pontos pontilhados ("40q"? "Quaddy-quad"? "Cutie-q"?).

Então vá em frente e aprenda algumas bases numéricas . Você será capaz de se exibir e ser a vida das festas e, como se costuma dizer, existem 10 tipos de pessoas: quem conhece binário e quem não conhece.

Não vamos nem pensar em endereços IPv6; Eu acho que eles são um dos 111 selos !!!

Synetech
fonte
39
Supercomplicar? A experimentação pode ser muito útil e, nesse caso, produziu uma boa resposta; mas sem uma teoria, documentação ou padrões, você pode estar perdendo um fator crítico e não o conhecer. Ou você pode determinar como uma versão específica funciona e estar errada em cerca de 90% das implementações existentes. Ou você pode criar regras que explicam os resultados de suas experiências, mas são mais complicadas do que as regras pretendidas. Nesse caso, acho que as regras da documentação (para inet_aton()) são mais simples em um aspecto - sem condicionais para "abaixo / acima de 255".
LarsH 12/10
71
Ei, olha! A parte "ciência" da Ciência da Computação aparece! (hypothesize, experimento, verificar)
Izkata
13
@LarsH, esse é o meu ponto, porém, que o pingcomando (pelo menos no Windows) é como muitos dos programas da Microsoft (especialmente o notório) IE. Ele tenta perdoar demais, pega tudo o que você joga e tenta interpretá-lo. Sim, existe um documento oficial sobre os formatos de endereço IP, mas isso não é uma pergunta sobre ISOs e RFCs, é prático, fiz algo e está sendo uma pergunta estranha que pode ser respondida sem recurso a (reconhecidamente longo, seco, chato especificações técnicas) - embora seja bom vinculá-las caso o OP queira lê-las também.
Synetech 12/12
6
A análise octal com prefixo 0 deve ser completamente abandonada, exceto por chmod. É isso aí. Essa é a única exceção para octal permitida. Período.
James Dunne
6
é útil para conversão de RGB HEX em DEC. lol ~C:\>ping 0xffffcc Pinging 0.255.255.204 with 32 bytes of data:
wilson
147

Há duas razões para isso:

Primeiro, um prefixo '0' indica um número octal . Desde outubro (072) = dec (58), 192.168.072 = 192.168.58.

Segundo, o penúltimo 0 pode ser eliminado dos endereços IP como uma abreviação . 127.0.1 é interpretado como 127.0.0.1 e, no seu caso, 192.168.58 é interpretado como 192.168.0.58.

neu242
fonte
7
Não agrupa zeros. Na verdade, trata cada ponto como um separador correspondente ao próximo limite de bytes. Portanto, os endereços IP 2130706433 e 127.0.0.1 são os mesmos endereços.
Serge
2
mais precisly É o quad notação pontilhada no caso de um endereço IP
Guillaume86
4
O famoso líder zero atingiu mais uma vez!
12752 Luc M #
2
agora esta é a verdadeira resposta!
l
2
Essa resposta é incorreta e enganosa. Soltar um 0 em 1.0.2.3 (1.2.3) fornece um endereço IP diferente (1.2.0.3).
sch 12/10
101

Além do ponto importante do @ neu242 sobre a notação octal e a observação de que os endereços IP podem ser encurtados, a outra parte crítica é saber como os endereços IP encurtados são interpretados.

Pode-se adivinhar ingenuamente que se alguns dos quatro números estiverem ausentes, o analisador adicionará bytes preenchidos com zero no final (ou no início) da sequência de bytes. Mas isso não corresponde ao comportamento relatado pelo OP: 192.168.072 foi analisado como 192.168. 0 .58, não como 192.168.58. 0 , nem 0, 192.168.58.

Aparentemente, o ping do Windows e Linux (a versão que você tentou e a que tentei) usa algo equivalente a inet_aton () para analisar o argumento do endereço IP. A página de manual para inet_aton () diz:

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.

Então aí está ... 192.168.072se encaixa no padrão abc, então o 072(depois de analisar como um número octal) foi interpretado como um valor de 16 bits que define os 2 bytes mais à direita do endereço binário, equivalente a 0.58.

As regras acima são equivalentes a dizer que, se algum dos quatro números estiver faltando, os bytes necessários preenchidos com zero serão adicionados imediatamente antes do último número fornecido ... não no final nem no início da sequência de bytes. (Expressá-lo dessa maneira funciona se o último número fornecido for menor que 256.)

Observe que versões mais recentes do ping podem não permitir esse tipo de abreviação, nem a interpretação octal. O código-fonte de 2010 para iputils (incluindo ping) que encontrei usa inet_pton () em vez de inet_aton () para analisar o argumento do endereço IP. A página de manual para inet_pton () diz:

Diferentemente de inet_aton (3) e inet_addr (3), inet_pton () suporta endereços IPv6. Por outro lado, inet_pton () aceita apenas endereços IPv4 em notação decimal com pontos, enquanto inet_aton (3) e inet_addr (3) permitem a notação mais geral de números e pontos (formatos de números hexadecimais e octais e formatos que não são " requer que todos os quatro bytes sejam escritos explicitamente).

LarsH
fonte
12
Esta é de longe a melhor resposta IMHO.
21712 Josh
No Windows que você está procurando inet_addrno Winsock.
user7116
24

Você deve considerar também que um ip pode ser representado por números inteiros somados em significado à sua posição.

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

Aqui está a coisa legal:

192.168.58 será 192.168.0.58 porque

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

192.11010106 também será 192.168.0.58 porque

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

3232235578 também será 192.168.0.58 porque

  192 * 256^3 
+ 168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 3232235578
vesquam
fonte
1
"192.168.56 será 192.168.0.56 porque 0 * 256 ^ 1 + 58 * 256 ^ 0 = 58" Você tem certeza? Você esperaria que 168 fossem multiplicados por 256 ^ 1 no primeiro caso e por 256 ^ 2 no segundo caso. Da mesma forma, 192 seria multiplicado por 256 ^ 2 vs. 256 ^ 3. Portanto, 192.168.56 poderia apenas = 192.168.0.56 se houver regras adicionais em vigor, como queda de zeros.
LarsH # 12/12
@LarsH, acho que o que está sendo dito aqui é que é baseado da esquerda para a direita, ao contrário da contagem "normal", na qual baseamos tudo do lugar do 1. Portanto, o primeiro ponto faz com que o que estiver à esquerda seja multiplicado por 256 ^ 3, o segundo por 256 ^ 2 e o terceiro por 256. se não houver ponto à esquerda, será adicionado sem multiplicar por 256 ^ n. Então 1.2.3. (1.2.3.0) seria diferente de 1.2.3 (1.2.0.3), se bem entendi.
iX3 12/10/12
@ iX3: se esse fosse o caso, "192.168.56 será 192.168.0.56" estaria incorreto, porque no primeiro caso, 56 seriam multiplicados por 256 ^ 1, enquanto no segundo caso, 56 seriam multiplicados apenas y 256 ^ 0. E o PO 192.168.072 seria interpretado como 192.168.58.0 em vez de 192.168.0.58.
LarsH # 12/12
O que é um pouco enganador é o fato de o endereço ter 0 e ter o terceiro dígito. Considere este endereço 192.168.1.56 O formulário de 3 dígitos seria 192.168.312 Como 1 * 256 ^ 1 + 56 * 256 ^ 0 é 312
vesquam 12/12/12
1
Os pontos servem apenas para delinear quais números devem ser multiplicados por qual potência de 256. O analisador procura o primeiro ponto e multiplica o número anterior por 256 ^ 3. Repita para o 2º e o 3º ponto, mas com 256 ^ 2 e 256 ^ 1, respectivamente. Em seguida, adiciona todos os resultados (alguns implementos podem manter um total contínuo, embora o resultado seja o mesmo). Se algum desses pontos estiver faltando, ele simplesmente não faz a multiplicação e apenas adiciona o número final ao total em execução. É também por isso que 1.2.3.resulta em um erro, porque o analisador não consegue encontrar o último número a ser adicionado ao total.
Justin ᚅᚔᚈᚄᚒᚔ