Stampa tutti gli indirizzi IPv4 unicast pubblici validi validi


10

Gli indirizzi IPv4 hanno una larghezza di 32 bit e quindi la dimensione dello spazio degli indirizzi è 2 32 o 4.294.967.296. Tuttavia, questo è solo un limite superiore teorico. Non è una rappresentazione accurata di tutti gli indirizzi che possono essere effettivamente utilizzati su Internet pubblico.

Ai fini di questa sfida, si presume che tutti gli indirizzi siano di classe . In realtà, la suddivisione di classe dello spazio degli indirizzi è stata sostituita dal CIDR (Classless Inter-Domain Routing e VLSM (Variable Length Subnet Masking) , ma questo viene ignorato per questa sfida.

Secondo lo schema di indirizzi di classe, ci sono 3 classi:

  • Classe A - 0.0.0.0a 127.255.255.255con /8lunghezza di maschera di rete
  • Classe B - 128.0.0.0a 191.255.255.255con /16lunghezza di maschera di rete
  • Classe C - 192.0.0.0a 223.255.255.255con /24lunghezza di maschera di rete

Sono definite anche le classi D (multicast) ed E (riservato), ma non utilizzate per gli indirizzi unicast pubblici.

Ogni classe è suddivisa in reti in base alla maschera di rete per quella classe.

Quindi 3.0.0.0è un esempio di una rete di classe A. La lunghezza maschera di rete per la Classe A è 8, quindi lo spazio indirizzo completo per questa rete è 3.0.0.0a 3.255.255.255. Tuttavia, il primo indirizzo ( 3.0.0.0) è riservato come indirizzo di rete e l'ultimo indirizzo ( 3.255.255.255) è riservato come indirizzo di trasmissione per quella rete. Pertanto, l'intervallo effettivo di indirizzi utilizzabili è pari 3.0.0.1a 3.255.255.2542 24 - 2 (= 16.777.214) indirizzi totali.

Allo stesso modo, 200.20.30.0è un esempio di una rete di classe C. La lunghezza maschera di rete per la Classe C è di 24, quindi lo spazio indirizzo completo per questa rete è 200.20.30.0a 200.20.30.255. Rimozione sugli indirizzi di rete e broadcast foglie la portata effettiva di indirizzi utilizzabili sia 200.20.30.1per 200.20.30.254cui è 2 8 - 2 (= 254) indirizzi totali.

Esistono ulteriori limitazioni sugli intervalli di indirizzi che possono essere utilizzati per l'unicast pubblico. Secondo RFC 6890 , le gamme non consentite sono:

  • 0.0.0.0/8 - Networking locale
  • 10.0.0.0/8 - Uso privato
  • 100.64.0.0/10 - Spazio indirizzi condiviso
  • 127.0.0.0/8 - Loopback
  • 169.254.0.0/16 - Collegamento locale
  • 172.16.0.0/12- Uso privato
  • 192.0.0.0/24 - Assegnazioni protocollo IETF
  • 192.0.2.0/24 - Riservato per l'uso nella documentazione
  • 192.88.99.0/24 - 6to4 relè Anycast
  • 192.168.0.0/16 - Uso privato
  • 198.18.0.0/15 - Analisi comparativa
  • 198.51.100.0/24 - Riservato per l'uso nella documentazione
  • 203.0.113.0/24 - Riservato per l'uso nella documentazione

Si noti che l'elenco sopra utilizza maschere di rete VLSR per specificare in modo efficiente un intervallo. In tutti i casi tranne uno, la lunghezza della maschera specificata ha specificità inferiore o uguale alla lunghezza della maschera normale normale per l'inizio dell'intervallo. Pertanto, ciascuno di questi intervalli VLSR equivale a una o più reti di classe. Ad esempio 172.16.0.0/12è equivalente alle reti 172.16.0.0di classe B 172.31.0.0o all'intervallo di indirizzi 172.16.0.0a 172.31.255.255.

L'eccezione a questa regola è l' 100.64.0.0/10intervallo VLSR, che è più specifico dell'intervallo di 100.0.0.0classe A contenente . Pertanto 100.0.0.0verrà gestito come altri intervalli di classe A, con l'eccezione che ha un foro di 4.194.304 indirizzi nel mezzo. Gli indirizzi validi in questo intervallo di Classe A saranno 100.0.0.0verso 100.63.255.255e 100.128.0.0verso 100.255.255.254, per un totale di 2 24 - 2 22 - 2 (= 12.582.910) indirizzi totali.

L'obiettivo di questa sfida è fornire tutti gli indirizzi IPv4 unicast di classe A, B e C che possono essere validamente assegnati a un host Internet pubblico (vale a dire escludendo quelli descritti sopra).

  • Non verrà fornito alcun input e non dovrebbe essere previsto.

  • L'output può essere in qualsiasi forma conveniente per la tua lingua, ad esempio array, elenco, stringa delimitata. Gli indirizzi devono essere emessi in formato decimale puntato standard.

  • L'ordine di uscita non ha importanza.

  • Non sono consentiti builtin che specificatamente forniscono gli intervalli di indirizzi richiesti. Allo stesso modo è vietato qualsiasi metodo per ispezionare dinamicamente una tabella di routing BGP (o altro protocollo) per Internet pubblica.

L'indirizzo numericamente più basso sarà 1.0.0.1e quello numericamente più alto sarà 223.255.255.254.


Questa sfida è simile a Stampa tutti gli indirizzi IPv6 , ma a causa delle restrizioni dovrebbe richiedere un'implementazione non banalmente diversa.

Risposte:


2

PowerShell, 648 641 625 byte

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

Modifica 1 - Ho eliminato tutte le potenze di due operatori rimanenti, risparmiando altri 7 byte.
Modifica 2: il [uint64]cast è stato spostato nella prima dichiarazione, $aeliminando gli altri due rilanci che hanno salvato 16 byte.

Tre righe, Classe A / Classe B / Classe C. A sinistra come righe separate per la leggibilità. ;-)

Due punti chiave per capire cosa sta succedendo:

  • PowerShell ha due poteri di due operatori KB, MB, GB. Ad esempio, 4KBtornerà 4096come int. Lo sfruttiamo in più posizioni per radere dozzine di byte.
  • La [ipaddress]classe .NET tenterà di analizzare un valore numerico come indirizzo IP prendendo la rappresentazione binaria del numero. Usiamo quel costruttore con l' IPAddressToStringargomento per l'output.

Associando queste due cose, siamo in grado di trattare semplicemente gli indirizzi IP come numeri e di eseguirne il ciclo con un for()ciclo. Ad esempio, il primo ciclo per le sottoreti di classe A va da 16MBa 2GB-16MBo da 16777216a 2130706432. La rappresentazione binaria di 16777216è 1000000000000000000000000o 00000001.00000000.00000000.00000000se la dividiamo in blocchi di 8 bit in modo da poter vedere facilmente che corrisponde alla 1.0.0.0notazione decimale puntata. Allo stesso modo, 2130706432può essere scritto come 01111111000000000000000000000000o 01111111.00000000.00000000.00000000o 127.0.0.0. In questo modo è possibile riscrivere come intero un indirizzo intero, o potenza di due interi, qui utilizzato.

Quindi, per ogni iterazione di loop, costruiamo if()un'istruzione per eliminare gli indirizzi esclusi, moltiplicando le singole istruzioni insieme. Poiché la prima istruzione in ciascuna ifè un numero intero (grazie al modulo testing), i valori booleani rimanenti vengono convertiti in uno 0o 1per false / true. Se una qualsiasi delle affermazioni è falsa, l'intera moltiplicazione si trasformerà in 0e quindi sarà falsa. Pertanto, solo se tutte le affermazioni sono vere, restituiremo il risultato dell'analisi.

Leggermente 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

Lotto, 1930 1884 1848 1830 byte

@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

Modifica: salvato 46 82 byte rimuovendo gli spazi non necessari. Salvato 18 byte utilizzando exit/binvece di goto:eof.


1
Conto 1872 byte. È tecnicamente non è necessario il @echo off, pure.
Addison Crump,

@FlagAsSpam Probabilmente CR; A Blocco note piace salvarli.
Neil,

Penso che tu possa rimuoverli, poiché contiamo per byte Unix UTF-8.
Addison Crump,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.