Saída de todos os endereços IPv4 unicast públicos classful válidos


10

Os endereços IPv4 têm 32 bits de largura e, portanto, o tamanho do espaço de endereço é 2 32 ou 4.294.967.296. No entanto, este é apenas um limite superior teórico. Não é uma representação precisa de todos os endereços que realmente podem ser usados ​​na Internet pública.

Para os propósitos deste desafio, supõe-se que todo o endereçamento seja de classe . Na realidade, a subdivisão de classe do espaço de endereço foi substituída pelo CIDR (roteamento entre domínios sem classe e VLSM (mascaramento de sub-rede de comprimento variável) , mas isso é ignorado para esse desafio.

De acordo com o esquema de endereço classful, existem 3 classes:

  • Classe A - 0.0.0.0para 127.255.255.255com /8comprimento máscara
  • Classe B - 128.0.0.0para 191.255.255.255com /16comprimento da máscara de rede
  • Classe C - 192.0.0.0para 223.255.255.255com /24comprimento máscara

As classes D (multicast) e E (reservadas) também são definidas, mas não são usadas para endereços unicast públicos.

Cada classe é subdividida em redes de acordo com a máscara de rede para essa classe.

Assim, 3.0.0.0é um exemplo de uma rede de classe A. O comprimento máscara de rede para a classe A é de 8, de modo que o espaço de endereço completo para esta rede é 3.0.0.0a 3.255.255.255. No entanto, o primeiro endereço ( 3.0.0.0) é reservado como endereço de rede e o último endereço ( 3.255.255.255) é reservado como endereço de transmissão para essa rede. Assim, a gama efectiva de endereços utilizáveis é 3.0.0.1a 3.255.255.254que é de 2 24 de - 2 (= 16.777.214) endereços totais.

Da mesma forma, 200.20.30.0é um exemplo de rede de Classe C. O comprimento máscara de rede para a classe C é de 24, de modo que o espaço de endereço total para esta rede é 200.20.30.0a 200.20.30.255. A remoção dos endereços de rede e transmissão deixa o intervalo real de endereços utilizáveis 200.20.30.1para o 200.20.30.254qual são 2 8 - 2 (= 254) endereços totais.

Existem outras limitações nos intervalos de endereços que podem ser usados ​​para unicast público. De acordo com a RFC 6890 , os intervalos não permitidos são:

  • 0.0.0.0/8 - Rede local
  • 10.0.0.0/8 - Uso privado
  • 100.64.0.0/10 - Espaço de Endereço Compartilhado
  • 127.0.0.0/8 - Loopback
  • 169.254.0.0/16 - Link Local
  • 172.16.0.0/12- Uso privado
  • 192.0.0.0/24 - Atribuições do protocolo IETF
  • 192.0.2.0/24 - Reservado para uso em documentação
  • 192.88.99.0/24 - Relé 6to4 Anycast
  • 192.168.0.0/16 - Uso privado
  • 198.18.0.0/15 - Avaliação comparativa
  • 198.51.100.0/24 - Reservado para uso em documentação
  • 203.0.113.0/24 - Reservado para uso em documentação

Observe que a lista acima usa máscaras de rede VLSR para especificar com eficiência um intervalo. Em todos os casos, exceto um, o comprimento da máscara fornecido tem especificidade menor ou igual ao comprimento normal da máscara classful para o início do intervalo. Assim, cada um desses intervalos VLSR é equivalente a uma ou mais redes classful. Por exemplo, 172.16.0.0/12é equivalente às redes de Classe B 172.16.0.0para 172.31.0.0ou o intervalo de endereços 172.16.0.0para 172.31.255.255.

A exceção a esta regra é o 100.64.0.0/10intervalo VLSR, que é mais específico que o 100.0.0.0intervalo Classe A que contém . Assim 100.0.0.0, será tratado como outros intervalos de classe A, com a exceção de que possui um orifício de 4.194.304 endereços no meio. Os endereços válidos nesse intervalo de Classe A serão 100.0.0.0de 100.63.255.255e 100.128.0.0para 100.255.255.254, um total de 2 24 - 2 22 - 2 (= 12.582.910) total de endereços.

O objetivo deste desafio é produzir todos os endereços IPv4 unicast de Classe A, B e C que possam ser atribuídos validamente a um host público da Internet (excluindo os detalhados acima).

  • Nenhuma entrada será fornecida e não deve ser esperada.

  • A saída pode ser de qualquer forma conveniente para o seu idioma, por exemplo, array, lista, string delimitada. Os endereços devem ser impressos no formato decimal pontilhado padrão.

  • A ordem de saída não importa.

  • Os componentes internos que fornecem especificamente os intervalos de endereços necessários não são permitidos. Da mesma forma, quaisquer métodos para inspecionar dinamicamente uma tabela de roteamento BGP (ou outro protocolo) da Internet pública são proibidos.

O endereço numericamente mais baixo será 1.0.0.1e o numericamente mais alto será 223.255.255.254.


Esse desafio é semelhante ao Imprimir todos os endereços IPv6 , mas devido às restrições deve exigir uma implementação não trivialmente diferente.

Respostas:


2

PowerShell, 648 641 625 bytes

for([uint64]$a=16MB;$a-lt2GB-16mb;$a++){if(($a%16mb)*(($a+1)%16mb)*($a-lt160MB-or$a-gt176MB)*($a-lt1604MB-or$a-ge1608MB)){([ipaddress]$a).IPAddressToString}}
for($a=2GB;$a-lt3GB;$a++){if(($a%64kb)*(($a+1)%64kb)*($a-lt2785152kb-or$a-gt2720mb)*($a-lt2753mb-or$a-gt2754mb)){([ipaddress]$a).IPAddressToString}}
for($a=3221225728;$a-lt3.5GB;$a++){if(($a%256)*(($a+1)%256)*(($a-lt3221225984-or$a-gt3221226240))*(($a-lt3227017984-or$a-gt3151385kb))*(($a-lt3156480kb-or$a-gt3156544kb))*(($a-lt3245184kb-or$a-gt3245312kb))*(($a-lt3247321kb-or$a-gt3325256959))*(($a-lt3405803776-or$a-gt3405804032))){([ipaddress]$a).IPAddressToString}}

Edição 1 - Joguei fora todos os poderes de dois operadores restantes, o que economizou 7 bytes adicionais.
Editar 2 - Moveu o [uint64]elenco para a primeira declaração, $aeliminando os outros dois relançamentos que salvaram 16 bytes.

Três linhas, Classe A / Classe B / Classe C. Deixadas como linhas separadas para facilitar a leitura. ;-)

Dois pontos-chave para entender o que está acontecendo:

  • O PowerShell possui dois operadores de potência KB, MB, GB. Por exemplo, 4KBretornará 4096como um int. Aproveitamos isso em vários locais para barbear dezenas de bytes.
  • A [ipaddress]classe .NET tentará analisar um valor numérico como um endereço IP, obtendo a representação binária do número. Usamos esse construtor com o IPAddressToStringargumento para output.

Ao unir essas duas coisas, somos capazes de tratar os endereços IP como números e fazer um loop através deles com um for()loop. Por exemplo, o primeiro loop para sub-redes de classe A passa de 16MBpara 2GB-16MBou de 16777216para 2130706432. A representação binária de 16777216é 1000000000000000000000000ou 00000001.00000000.00000000.00000000se a dividimos em partes de 8 bits, para que possamos ver facilmente que corresponde à 1.0.0.0notação decimal com pontos. Da mesma forma, 2130706432pode ser escrito como 01111111000000000000000000000000ou 01111111.00000000.00000000.00000000ou 127.0.0.0. Cada número inteiro, ou número inteiro de dois em dois, usado aqui pode ser reescrito como um endereço IP dessa maneira.

Portanto, para cada iteração de loop, construímos uma if()instrução para eliminar os endereços excluídos, multiplicando as instruções individuais. Como a primeira instrução em cada ifuma é um número inteiro (graças ao teste do módulo), os valores booleanos restantes são convertidos em 0ou 1para falso / verdadeiro. Se qualquer uma das afirmações for falsa, toda a multiplicação se tornará 0e, portanto, será falsa. Assim, somente se todas as afirmações forem verdadeiras, produziremos o resultado da análise.

Ligeiramente Ungolfed:

# Class A
for($a=16MB;$a-lt2GB-16mb;$a++){
  $b=($a%16mb)                     # x.0.0.0
  $b*=(($a+1)%16mb)                # x.255.255.255
  $b*=($a-lt160MB-or$a-gt176MB)    # 10.0.0.0/8
  $b*=($a-lt1604MB-or$a-ge1608MB)  # 100.64.0.0/10
  if($b){([ipaddress]::Parse($a)).IPAddressToString}
}

# Class B
for($a=2GB;$a-lt3GB;$a++){
  $b=($a%64kb)                           # x.y.0.0
  $b*=(($a+1)%64kb)                      # x.y.255.255
  $b*=(($a-lt2785152kb-or$a-gt2720mb))  # 169.254.0.0/16
  $b*=(($a-lt2753mb-or$a-gt2754mb))      # 172.16.0.0/12
  if($b){([ipaddress]::Parse($a)).IPAddressToString}
}

# Class C
for($a=3221225728;$a-lt3.5GB;$a++){
  $b=($a%256)                               # x.y.z.0
  $b*=(($a+1)%256)                          # x.y.z.255
  $b*=(($a-lt3221225984-or$a-gt3221226240)) # 192.0.2.0/24
  $b*=(($a-lt3227017984-or$a-gt3151385kb)) # 192.88.99.0/24
  $b*=(($a-lt3156480kb-or$a-gt3156544kb)) # 192.168.0.0/16
  $b*=(($a-lt3245184kb-or$a-gt3245312kb)) # 198.18.0.0/15
  $b*=(($a-lt3247321kb-or$a-gt3325256959)) # 198.51.100.0/24
  $b*=(($a-lt3405803776-or$a-gt3405804032)) # 203.0.113.0/24
  if($b){([ipaddress]::Parse($a)).IPAddressToString}
}

1

Lote, 1930 1884 1848 1830 bytes

@echo off
for /l %%a in (1,1,9)do call:a1 %%a
for /l %%a in (11,1,99)do call:a1 %%a
for /l %%b in (0,1,63)do call:a2 100 %%b
for /l %%b in (128,1,255)do call:a2 100 %%b
for /l %%a in (101,1,126)do call:a1 %%a
for /l %%a in (128,1,168)do call:b1 %%a
for /l %%b in (0,1,253)do call:b2 169 %%b
call:b2 169 255
call:b1 170
call:b1 171
for /l %%b in (0,1,15)do call:b2 172 %%b
for /l %%b in (32,1,255)do call:b2 172 %%b
for /l %%a in (173,1,191)do call:b1 %%a
call:c3 192 0 1
for /l %%c in (3,1,255)do call:c3 192 0 %%c
for /l %%b in (1,1,87)do call:c2 192 %%b
for /l %%c in (0,1,98)do call:c3 192 88 %%c
for /l %%c in (100,1,255)do call:c3 192 88 %%c
for /l %%b in (89,1,167)do call:c2 192 %%b
for /l %%b in (169,1,255)do call:c2 192 %%b
for /l %%a in (193,1,197)do call:c1 %%a
for /l %%b in (0,1,17)do call:c2 198 %%b
for /l %%b in (20,1,50)do call:c2 198 %%b
for /l %%c in (0,1,99)do call:c3 198 51 %%c
for /l %%c in (101,1,255)do call:c3 198 51 %%c
for /l %%b in (52,1,255)do call:c2 198 %%b
for /l %%a in (199,1,202)do call:c1 %%a
for /l %%c in (0,1,112)do call:c3 203 0 %%c
for /l %%c in (114,1,255)do call:c3 203 0 %%c
for /l %%b in (1,1,255)do call:c2 203 %%b
for /l %%a in (204,1,223)do call:c1 %%a
exit/b
:a1
for /l %%b in (0,1,255)do call:a2 %1 %%b
exit/b
:a2
for /l %%c in (0,1,255)do call:a3 %1 %2 %%c
exit/b
:a3
for /l %%d in (0,1,255)do if not %2%3%%d==000 if not %2%3%%d==255255255 echo %1.%2.%3.%%d
exit/b
:b1
for /l %%b in (0,1,255)do call:b2 %1 %%b
exit/b
:b2
for /l %%c in (0,1,255)do call:b3 %1 %2 %%c
exit/b
:b3
for /l %%d in (0,1,255)do if not %3%%d==00 if not %3%%d==255255 echo %1.%2.%3.%%d
exit/b
:c1
for /l %%b in (0,1,255)do call:c2 %1 %%b
exit/b
:c2
for /l %%c in (0,1,255)do call:c3 %1 %2 %%c
exit/b
:c3
for /l %%d in (1,1,254)do echo %1.%2.%3.%%d

Editar: salvou 46 82 bytes removendo espaços desnecessários. Salva 18 bytes usando em exit/bvez de goto:eof.


11
Eu conto 1872 bytes. Você tecnicamente não precisa do @echo offtambém.
Addison Crump

@FlagAsSpam Provavelmente CRs; O bloco de notas gosta de salvá-los.
Neil

Eu acho que você pode removê-los, uma vez que contamos por Unix UTF-8 bytes.
Addison Crump
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.