Sortie de toutes les adresses IPv4 publiques unicast valides avec classe


10

Les adresses IPv4 ont une largeur de 32 bits, et donc la taille de l'espace d'adressage est de 2 32 ou 4 294 967 296. Cependant, ce n'est qu'une limite supérieure théorique. Il ne s'agit pas d'une représentation précise de toutes les adresses qui peuvent effectivement être utilisées sur l'Internet public.

Aux fins de ce défi, il est supposé que tout adressage est de classe . En réalité, la subdivision classe de l'espace d'adressage a été remplacée par le CIDR (Classless Inter-Domain Routing et VLSM (Variable Length Subnet Masking)) , mais cela est ignoré pour ce défi.

Selon le schéma d'adresse par classe, il existe 3 classes:

  • Classe A - 0.0.0.0à 127.255.255.255avec /8longueur de masque de réseau
  • Classe B - 128.0.0.0à 191.255.255.255avec /16longueur de masque de réseau
  • Classe C - 192.0.0.0à 223.255.255.255avec /24longueur de masque de réseau

Les classes D (multidiffusion) et E (réservées) sont également définies, mais elles ne sont pas utilisées pour les adresses de monodiffusion publiques.

Chaque classe est subdivisée en réseaux selon le masque de réseau de cette classe.

3.0.0.0Voici donc un exemple de réseau de classe A. La longueur du masque de réseau pour la classe A est 8, donc l'espace d'adressage complet de ce réseau est 3.0.0.0de 3.255.255.255. Cependant, la première adresse ( 3.0.0.0) est réservée comme adresse réseau et la dernière adresse ( 3.255.255.255) est réservée comme adresse de diffusion pour ce réseau. Ainsi, la plage réelle d'adresses utilisables est celle 3.0.0.1à 3.255.255.254laquelle se trouvent 2 24 - 2 (= 16 777 214) adresses totales.

De même, 200.20.30.0est un exemple de réseau de classe C. La longueur du masque de réseau pour la classe C est de 24, donc l'espace d'adressage complet de ce réseau est 200.20.30.0de 200.20.30.255. La suppression des adresses de réseau et de diffusion laisse la plage réelle d'adresses utilisables 200.20.30.1à 200.20.30.254laquelle se situent 2 8 - 2 (= 254) adresses totales.

Il existe d'autres limitations sur les plages d'adresses qui peuvent être utilisées pour la monodiffusion publique. Selon la RFC 6890 , les plages interdites sont les suivantes:

  • 0.0.0.0/8 - Réseautage local
  • 10.0.0.0/8 - Usage privé
  • 100.64.0.0/10 - Espace d'adressage partagé
  • 127.0.0.0/8 - Boucle
  • 169.254.0.0/16 - Lien local
  • 172.16.0.0/12- Usage privé
  • 192.0.0.0/24 - Affectations de protocole IETF
  • 192.0.2.0/24 - Réservé pour une utilisation dans la documentation
  • 192.88.99.0/24 - Anycast relais 6to4
  • 192.168.0.0/16 - Usage privé
  • 198.18.0.0/15 - Analyse comparative
  • 198.51.100.0/24 - Réservé pour une utilisation dans la documentation
  • 203.0.113.0/24 - Réservé pour une utilisation dans la documentation

Notez que la liste ci-dessus utilise des masques de réseau VLSR pour spécifier efficacement une plage. Dans tous les cas sauf un, la longueur de masque donnée a une spécificité inférieure ou égale à la longueur de masque de classe normale pour le début de la plage. Ainsi, chacune de ces plages VLSR équivaut à un ou plusieurs réseaux avec classe. Par exemple , 172.16.0.0/12est équivalent aux réseaux de classe B 172.16.0.0à 172.31.0.0ou la plage d'adresses 172.16.0.0à 172.31.255.255.

L'exception à cette règle est la 100.64.0.0/10plage VLSR, qui est plus spécifique que la 100.0.0.0plage de classe A contenant . Ainsi, 100.0.0.0il sera traité comme les autres gammes de classe A, à l'exception qu'il a un trou d'adresse de 4 194 304 adresses au milieu. Les adresses valides dans cette plage de classe A seront 100.0.0.0vers 100.63.255.255et 100.128.0.0vers 100.255.255.254, un total de 2 24 - 2 22 - 2 (= 12 582 910) adresses totales.

Le but de ce défi est de produire toutes les adresses IPv4 unicast de classe A, B et C qui peuvent être valablement attribuées à un hôte Internet public (c'est-à-dire à l'exclusion de celles détaillées ci-dessus).

  • Aucune contribution ne sera donnée et ne devrait pas être attendue.

  • La sortie peut être sous n'importe quelle forme convenant à votre langue, par exemple tableau, liste, chaîne délimitée. Les adresses doivent être sorties au format décimal pointé standard.

  • L'ordre de sortie n'a pas d'importance.

  • Les fonctions intégrées qui donnent spécifiquement les plages d'adresses requises sont interdites. De même, toutes les méthodes pour inspecter dynamiquement une table de routage BGP (ou autre protocole) pour l'Internet public sont interdites.

L'adresse numériquement la plus basse sera 1.0.0.1et la numériquement la plus élevée sera 223.255.255.254.


Ce défi est similaire à Imprimer toutes les adresses IPv6 , mais en raison des restrictions, il devrait nécessiter une implémentation non triviale différente.

Réponses:


2

PowerShell, 648 641 625 octets

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

Édition 1 - J'ai joué au golf tous les opérateurs de puissance de deux restants, ce qui a permis d'économiser 7 octets supplémentaires.
Edit 2 - Déplacé le [uint64]casting vers la première déclaration, $ace qui a éliminé les deux autres re-castes qui ont sauvé 16 octets.

Trois lignes, Classe A / Classe B / Classe C. Gauche comme lignes séparées pour plus de lisibilité. ;-)

Deux points clés pour comprendre ce qui se passe:

  • PowerShell dispose d'opérateurs au pouvoir de deux KB, MB, GB. Par exemple, 4KBretournera 4096en tant qu'int. Nous exploitons cela à plusieurs endroits pour raser des dizaines d'octets.
  • La [ipaddress]classe .NET essaiera d' analyser une valeur numérique en tant qu'adresse IP en prenant la représentation binaire du nombre. Nous utilisons ce constructeur avec l' IPAddressToStringargument de sortie.

En couplant ces deux choses, nous pouvons simplement traiter les adresses IP comme des nombres et les parcourir en for()boucle. Par exemple, la première boucle pour les sous-réseaux de classe A va de 16MBà 2GB-16MB, ou de 16777216à 2130706432. La représentation binaire de 16777216est 1000000000000000000000000ou 00000001.00000000.00000000.00000000si nous la divisons en morceaux de 8 bits afin que nous puissions facilement voir que cela correspond à la 1.0.0.0notation décimale à points. De même, 2130706432peut être écrit comme 01111111000000000000000000000000ou 01111111.00000000.00000000.00000000ou 127.0.0.0. Chaque entier, ou puissance de deux entiers, utilisé ici peut être réécrit comme une adresse IP de cette manière.

Ainsi, pour chaque itération de boucle, nous construisons une if()instruction pour éliminer les adresses exclues, en multipliant les instructions individuelles ensemble. Étant donné que la première instruction dans chacun ifest un entier (grâce aux tests modulo), les valeurs booléennes restantes sont converties en 0ou 1pour faux / vrai. Si l'une des affirmations est fausse, toute la multiplication se transformera 0et sera donc fausse. Ainsi, ce n'est que si toutes les déclarations sont vraies que nous afficherons le résultat de l'analyse.

Légèrement non 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

Lot, 1930 1884 1848 1830 octets

@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

Edit: économisé 46 82 octets en supprimant les espaces inutiles. Enregistré 18 octets en utilisant exit/bau lieu de goto:eof.


1
Je compte 1872 octets. Techniquement, vous n'en avez pas besoin non @echo offplus.
Addison Crump

@FlagAsSpam Probablement CR; Le bloc-notes aime les enregistrer.
Neil

Je pense que vous pouvez les supprimer, car nous comptons par octets Unix UTF-8.
Addison Crump
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.