Salida de todas las direcciones IPv4 unicast públicas con clase válidas


10

Las direcciones IPv4 tienen 32 bits de ancho y, por lo tanto, el tamaño del espacio de direcciones es 2 32 o 4,294,967,296. Sin embargo, esto es solo un límite superior teórico. No es una representación precisa de todas las direcciones que realmente se pueden usar en Internet público.

Para los propósitos de este desafío, se supone que todo direccionamiento es con clase . En realidad, la subdivisión con clase del espacio de direcciones ha sido reemplazada por CIDR (enrutamiento entre dominios sin clase y VLSM (enmascaramiento de subred de longitud variable) , pero esto se ignora para este desafío.

Según el esquema de direcciones con clase, hay 3 clases:

  • Clase A - 0.0.0.0a 127.255.255.255con /8longitud de máscara de red
  • Clase B - 128.0.0.0a 191.255.255.255con /16longitud de máscara de red
  • Clase C - 192.0.0.0a 223.255.255.255con /24longitud de máscara de red

Las clases D (multidifusión) y E (reservada) también se definen, pero no se utilizan para direcciones públicas de unidifusión.

Cada clase se subdivide en redes según la máscara de red para esa clase.

Por 3.0.0.0lo tanto, es un ejemplo de una red de clase A. La longitud de máscara de red de clase A es 8, por lo que el espacio de direcciones completa para esta red es 3.0.0.0a 3.255.255.255. Sin embargo, la primera dirección ( 3.0.0.0) está reservada como la dirección de red y la última dirección ( 3.255.255.255) está reservada como la dirección de difusión para esa red. Por lo tanto, el rango real de direcciones utilizables es 3.0.0.1a 3.255.255.2542 24 - 2 (= 16,777,214) direcciones totales.

Del mismo modo, 200.20.30.0es un ejemplo de una red de clase C. La longitud de máscara de red para la clase C es 24, por lo que el espacio de dirección completa para esta red es 200.20.30.0a 200.20.30.255. Extracción de las hojas direcciones de red y transmisión de la gama real de direcciones utilizable es 200.20.30.1a 200.20.30.254que es de 2 8 - 2 (= 254) direcciones en total.

Existen otras limitaciones en los rangos de direcciones que pueden usarse para unidifusión pública. De acuerdo con RFC 6890 , los rangos no permitidos son:

  • 0.0.0.0/8 - Redes locales
  • 10.0.0.0/8 - Uso privado
  • 100.64.0.0/10 - Espacio de direcciones compartidas
  • 127.0.0.0/8 - Loopback
  • 169.254.0.0/16 - Enlace local
  • 172.16.0.0/12- Uso privado
  • 192.0.0.0/24 - Asignaciones de protocolo IETF
  • 192.0.2.0/24 - Reservado para su uso en la documentación
  • 192.88.99.0/24 - 6to4 Relay Anycast
  • 192.168.0.0/16 - Uso privado
  • 198.18.0.0/15 - Benchmarking
  • 198.51.100.0/24 - Reservado para su uso en la documentación
  • 203.0.113.0/24 - Reservado para su uso en la documentación

Tenga en cuenta que la lista anterior usa máscaras de red VLSR para especificar eficientemente un rango. En todos los casos menos uno, la longitud de la máscara dada tiene una especificidad menor o igual que la longitud de la máscara con clase normal para el inicio del rango. Por lo tanto, cada uno de estos rangos de VLSR es equivalente a una o más redes con clase. Por ejemplo 172.16.0.0/12es equivalente a las redes de clase B 172.16.0.0a 172.31.0.0o el intervalo de direcciones 172.16.0.0a 172.31.255.255.

La excepción a esta regla es el 100.64.0.0/10rango VLSR, que es más específico que el 100.0.0.0rango Clase A que lo contiene . Por 100.0.0.0lo tanto , se manejará como otros rangos de Clase A con la excepción de que tiene un agujero de 4,194,304 direcciones en el medio. Las direcciones válidas en este rango de Clase A serán 100.0.0.0a 100.63.255.255y 100.128.0.0a 100.255.255.254, un total de 2 24 - 2 22 - 2 (= 12582910) direcciones en total.

El objetivo de este desafío es generar todas las direcciones IPv4 de unidifusión de Clase A, B y C que pueden asignarse de manera válida a un host de Internet público (es decir, excluyendo las detalladas anteriormente).

  • No se dará ninguna entrada y no se debe esperar.

  • La salida puede ser de cualquier forma conveniente para su idioma, por ejemplo, matriz, lista, cadena delimitada. Las direcciones deben enviarse en formato decimal con puntos estándar.

  • El orden de salida no importa.

  • Las incorporaciones que proporcionan específicamente los rangos de direcciones requeridos no están permitidas. Del mismo modo, no se permiten los métodos para inspeccionar dinámicamente una tabla de enrutamiento BGP (u otro protocolo) para Internet público.

La dirección numéricamente más baja será 1.0.0.1y la numéricamente más alta será 223.255.255.254.


Este desafío es similar a Imprimir todas las direcciones IPv6 , pero debido a las restricciones debería requerir una implementación no trivialmente diferente.

Respuestas:


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

Edición 1: he jugado todos los operadores restantes de potencias de dos, lo que ahorró 7 bytes adicionales.
Edición 2: movió el [uint64]elenco a la primera declaración, $aque eliminó los otros dos relanzamientos que ahorraron 16 bytes.

Tres líneas, Clase A / Clase B / Clase C. Izquierda como líneas separadas para facilitar la lectura. ;-)

Dos puntos clave para entender lo que está sucediendo:

  • PowerShell tiene operadores de poderes de dos KB, MB, GB. Por ejemplo, 4KBvolverá 4096como int. Aprovechamos eso en múltiples ubicaciones para reducir docenas de bytes.
  • La [ipaddress]clase .NET intentará analizar un valor numérico como una dirección IP tomando la representación binaria del número. Usamos ese constructor con el IPAddressToStringargumento para la salida.

Al acoplar esas dos cosas, podemos tratar las direcciones IP como números y recorrerlas con un for()bucle. Por ejemplo, el primer bucle para las subredes de Clase A va de 16MBa 2GB-16MB, o de 16777216a 2130706432. La representación binaria de 16777216es 1000000000000000000000000o 00000001.00000000.00000000.00000000si la dividimos en fragmentos de 8 bits para que podamos ver fácilmente que corresponde a la 1.0.0.0notación decimal con puntos. Del mismo modo, 2130706432se puede escribir como 01111111000000000000000000000000o 01111111.00000000.00000000.00000000o 127.0.0.0. Cada entero, o entero de potencia de dos, utilizado aquí puede reescribirse como una dirección IP de esta manera.

Entonces, para cada iteración de bucle, construimos una if()declaración para eliminar las direcciones excluidas, multiplicando las declaraciones individuales juntas. Dado que la primera instrucción en cada uno ifes un número entero (gracias a la prueba de módulo), los valores booleanos restantes se convierten a 0o 1para falso / verdadero. Si cualquiera de las declaraciones es falsa, la multiplicación completa se convertirá en 0y, por lo tanto, será falsa. Por lo tanto, solo si todas las declaraciones son verdaderas, mostraremos el resultado del análisis.

Ligeramente sin golf:

# 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: se guardaron 46 82 bytes eliminando espacios innecesarios. Se guardaron 18 bytes usando en exit/blugar de goto:eof.


1
Cuento 1872 bytes. Usted técnicamente no es necesario el @echo off, también.
Addison Crump

@FlagAsSpam Probablemente CR; El bloc de notas le gusta guardarlos.
Neil

Creo que puede eliminarlos, ya que contamos por bytes Unix UTF-8.
Addison Crump
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.