Geben Sie alle gültigen öffentlichen Unicast-IPv4-Adressen aus

10

IPv4-Adressen sind 32 Bit breit, und daher beträgt die Größe des Adressraums 2 32 oder 4 294 967 296. Dies ist jedoch nur eine theoretische Obergrenze. Es ist keine genaue Darstellung aller Adressen, die tatsächlich im öffentlichen Internet verwendet werden können.

Für die Zwecke dieser Herausforderung wird angenommen, dass alle Adressierungen klassisch sind . In der Realität wurde die klassische Unterteilung des Adressraums durch CIDR (Classless Inter-Domain Routing und VLSM (Subnetzmaskierung variabler Länge)) ersetzt , dies wird jedoch für diese Herausforderung ignoriert.

Nach dem Klassenadressschema gibt es 3 Klassen:

  • Klasse A - 0.0.0.0bis 127.255.255.255mit /8Netzmaskenlänge
  • Klasse B - 128.0.0.0bis 191.255.255.255mit /16Netzmaskenlänge
  • Klasse C - 192.0.0.0bis 223.255.255.255mit /24Netzmaskenlänge

Die Klassen D (Multicast) und E (reserviert) sind ebenfalls definiert, werden jedoch nicht für öffentliche Unicast-Adressen verwendet.

Jede Klasse ist gemäß der Netzmaske für diese Klasse in Netzwerke unterteilt.

Dies 3.0.0.0ist ein Beispiel für ein Klasse-A-Netzwerk. Die Netzmaskenlänge für Klasse A beträgt 8, daher ist der volle Adressraum für dieses Netzwerk 3.0.0.0zu 3.255.255.255. Die erste Adresse ( 3.0.0.0) ist jedoch als Netzwerkadresse reserviert, und die letzte Adresse ( 3.255.255.255) ist als Broadcast-Adresse für dieses Netzwerk reserviert. Somit ist der tatsächliche Bereich verwendbarer Adressen 3.0.0.1zu 3.255.255.254, die 2 24 - 2 (= 16.777.214) alle Adressen.

In ähnlicher Weise 200.20.30.0ist ein Beispiel für ein Klasse-C-Netzwerk. Die Netzmaskenlänge für Klasse C beträgt 24, daher ist der volle Adressraum für dieses Netzwerk 200.20.30.0zu 200.20.30.255. Durch das Entfernen der Netzwerk- und Broadcast-Adressen bleibt der tatsächliche Bereich der verwendbaren Adressen, 200.20.30.1zu 200.20.30.254denen 2 8 - 2 (= 254) Gesamtadressen gehören.

Es gibt weitere Einschränkungen für Adressbereiche, die für öffentliches Unicast verwendet werden können. Gemäß RFC 6890 sind die unzulässigen Bereiche:

  • 0.0.0.0/8 - Lokale Vernetzung
  • 10.0.0.0/8 - Privater Gebrauch
  • 100.64.0.0/10 - Gemeinsamer Adressraum
  • 127.0.0.0/8 - Loopback
  • 169.254.0.0/16 - Lokale Verbindung
  • 172.16.0.0/12- Privater Gebrauch
  • 192.0.0.0/24 - IETF-Protokollzuweisungen
  • 192.0.2.0/24 - Reserviert für die Verwendung in der Dokumentation
  • 192.88.99.0/24 - 6to4 Relay Anycast
  • 192.168.0.0/16 - Privater Gebrauch
  • 198.18.0.0/15 - Benchmarking
  • 198.51.100.0/24 - Reserviert für die Verwendung in der Dokumentation
  • 203.0.113.0/24 - Reserviert für die Verwendung in der Dokumentation

Beachten Sie, dass in der obigen Liste VLSR-Netzmasken verwendet werden, um einen Bereich effizient anzugeben. In allen bis auf einen Fall ist die Spezifität der angegebenen Maskenlänge kleiner oder gleich der normalen klassischen Maskenlänge für den Beginn des Bereichs. Somit entspricht jeder dieser VLSR-Bereiche einem oder mehreren klassischen Netzwerken. Eg 172.16.0.0/12ist äquivalent zu der Klasse B - Netzwerke 172.16.0.0zu 172.31.0.0oder den Adressbereich 172.16.0.0zu 172.31.255.255.

Die Ausnahme von dieser Regel ist der 100.64.0.0/10VLSR-Bereich, der spezifischer ist als der enthaltende 100.0.0.0Klasse-A-Bereich. Daher 100.0.0.0wird es wie andere Bereiche der Klasse A behandelt, mit der Ausnahme, dass es in der Mitte ein Loch mit 4.194.304 Adressen gibt. Die gültigen Adressen in diesem Bereich der Klasse A lauten 100.0.0.0auf 100.63.255.255und 100.128.0.0bis 100.255.255.254insgesamt 2 24 - 2 22 - 2 (= 12.582.910) Gesamtadressen.

Ziel dieser Herausforderung ist es, alle Unicast-IPv4-Adressen der Klassen A, B und C auszugeben, die einem öffentlichen Internet-Host gültig zugewiesen werden können (dh mit Ausnahme der oben beschriebenen).

  • Es wird keine Eingabe gegeben und sollte nicht erwartet werden.

  • Die Ausgabe kann in einer für Ihre Sprache geeigneten Form erfolgen, z. B. Array, Liste, begrenzte Zeichenfolge. Adressen müssen im Standardformat für gepunktete Dezimalstellen ausgegeben werden.

  • Ausgabereihenfolge spielt keine Rolle.

  • Builtins, die speziell die erforderlichen Adressbereiche angeben, sind nicht zulässig. Ebenso sind Methoden zur dynamischen Überprüfung einer BGP- Routing-Tabelle (oder einer anderen Protokoll-Routing-Tabelle) für das öffentliche Internet nicht zulässig.

Die numerisch niedrigste Adresse ist 1.0.0.1und die numerisch höchste Adresse 223.255.255.254.


Diese Herausforderung ähnelt dem Ausdrucken aller IPv6-Adressen , sollte jedoch aufgrund der Einschränkungen eine nicht trivial unterschiedliche Implementierung erfordern.

Digitales Trauma
quelle

Antworten:

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

Bearbeiten 1 - Ich habe alle verbleibenden Zweierpotenz-Operatoren herausgespielt, wodurch zusätzliche 7 Bytes eingespart wurden.
Bearbeiten 2 - Der [uint64]Cast wurde in die erste Deklaration verschoben, bei der $adie beiden anderen Re-Casts eliminiert wurden, wodurch 16 Bytes gespart wurden.

Drei Zeilen, Klasse A / Klasse B / Klasse C. Zur besseren Lesbarkeit als separate Zeilen links. ;-);

Zwei wichtige Punkte, um zu verstehen, was los ist:

  • PowerShell verfügt über zwei Potenzen KB, MB, GB. Zum Beispiel 4KBwird wieder 4096als int. Wir nutzen dies an mehreren Stellen, um Dutzende von Bytes zu rasieren.
  • Die .NET- [ipaddress]Klasse versucht, einen numerischen Wert als IP-Adresse zu analysieren, indem sie die Binärdarstellung der Zahl verwendet. Wir verwenden diesen Konstruktor mit dem IPAddressToStringArgument für die Ausgabe.

Durch die Kopplung dieser beiden Dinge können wir die IP-Adressen einfach als Zahlen behandeln und sie mit einer for()Schleife durchlaufen . Beispielsweise geht die erste Schleife für Subnetze der Klasse A von 16MBbis 2GB-16MBoder von 16777216bis 2130706432. Die binäre Darstellung von 16777216ist 1000000000000000000000000oder 00000001.00000000.00000000.00000000wenn wir sie in 8-Bit-Blöcke aufteilen, damit wir leicht erkennen können, dass dies der 1.0.0.0Punkt-Dezimal-Notation entspricht. Ebenso 2130706432kann als 01111111000000000000000000000000oder 01111111.00000000.00000000.00000000oder geschrieben werden 127.0.0.0. Jede hier verwendete Ganzzahl oder Zweierpotenz kann auf diese Weise als IP-Adresse umgeschrieben werden.

Daher erstellen wir für jede Schleifeniteration eine if()Anweisung, um die ausgeschlossenen Adressen auszusortieren, indem wir die einzelnen Anweisungen miteinander multiplizieren. Da die erste Anweisung in jeder ifeine Ganzzahl ist (dank des Modulo-Tests), werden die verbleibenden Booleschen Werte entweder in 0oder 1für false / true konvertiert . Wenn eine der Aussagen falsch ist, wird die gesamte Multiplikation 0falsch und somit falsch. Nur wenn alle Aussagen wahr sind, geben wir das Ergebnis der Analyse aus.

Leicht 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}
}
AdmBorkBork
quelle
1

Batch, 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

Bearbeiten: 46 82 Bytes durch Entfernen unnötiger Leerzeichen gespeichert . 18 Bytes durch Verwendung von exit/banstelle von gespeichert goto:eof.

Neil
quelle
1
Ich zähle 1872 Bytes. Das brauchen Sie technisch auch nicht @echo off.
Addison Crump
@FlagAsSpam Wahrscheinlich CRs; Notepad speichert sie gerne.
Neil
Ich denke, Sie können sie entfernen, da wir nach Unix UTF-8 Bytes zählen.
Addison Crump