Wyprowadza wszystkie prawidłowe klasowe publiczne adresy IPv4 emisji pojedynczej


10

Adresy IPv4 mają szerokość 32 bitów, a zatem rozmiar przestrzeni adresowej wynosi 2 32 lub 4 294 967 296. Jest to jednak tylko teoretyczna górna granica. Nie jest to dokładne przedstawienie wszystkich adresów, które mogą być faktycznie używane w publicznym Internecie.

Na potrzeby tego wyzwania zakłada się, że wszystkie adresowanie jest klasowe . W rzeczywistości podział klasowy przestrzeni adresowej został zastąpiony przez CIDR (Classless Inter-Domain Routing i VLSM (Variable Length Subnet Masking) , ale jest to ignorowane w przypadku tego wyzwania.

Zgodnie ze schematem adresów klasowych istnieją 3 klasy:

  • Klasa A - 0.0.0.0do 127.255.255.255o /8długości maski sieci
  • Klasa B - 128.0.0.0do 191.255.255.255o /16długości maski sieci
  • Klasa C - 192.0.0.0do 223.255.255.255o /24długości maski sieci

Klasy D (multiemisja) i E (zarezerwowane) są również zdefiniowane, ale nie są one używane w przypadku publicznych adresów emisji pojedynczej.

Każda klasa jest podzielona na sieci zgodnie z maską sieci dla tej klasy.

Tak więc 3.0.0.0jest przykładem sieci klasy A. Długość maska w klasie A wynosi 8, a więc pełna przestrzeń adresowa dla tej sieci jest 3.0.0.0do 3.255.255.255. Jednak pierwszy adres ( 3.0.0.0) jest zarezerwowany jako adres sieciowy, a ostatni adres ( 3.255.255.255) jest zarezerwowany jako adres rozgłoszeniowy dla tej sieci. Zatem rzeczywisty zakres adresów użytkowej 3.0.0.1na 3.255.255.254który jest 2 24 - 2 (= 16,777,214) łączne adresów.

Podobnie 200.20.30.0jest przykładem sieci klasy C. Długość maska dla klasy C jest 24, więc pełna przestrzeń adresowa dla tej sieci jest 200.20.30.0do 200.20.30.255. Usunięcie adresów sieciowych i rozgłoszeniowych pozostawia rzeczywisty zakres adresów użytecznych, 200.20.30.1do 200.20.30.254których jest 2 8 - 2 (= 254) adresów ogółem.

Istnieją dalsze ograniczenia zakresów adresów, które mogą być używane do publicznej emisji pojedynczej. Zgodnie z RFC 6890 niedozwolone zakresy to:

  • 0.0.0.0/8 - Lokalne sieci
  • 10.0.0.0/8 - Użytek prywatny
  • 100.64.0.0/10 - Wspólna przestrzeń adresowa
  • 127.0.0.0/8 - Loopback
  • 169.254.0.0/16 - Link lokalny
  • 172.16.0.0/12- Użytek prywatny
  • 192.0.0.0/24 - Przypisania protokołu IETF
  • 192.0.2.0/24 - Zarezerwowane do użytku w dokumentacji
  • 192.88.99.0/24 - Anycast 6to4 Relay
  • 192.168.0.0/16 - Użytek prywatny
  • 198.18.0.0/15 - Benchmarking
  • 198.51.100.0/24 - Zarezerwowane do użytku w dokumentacji
  • 203.0.113.0/24 - Zarezerwowane do użytku w dokumentacji

Należy zauważyć, że powyższa lista wykorzystuje maski sieci VLSR do skutecznego określania zakresu. We wszystkich przypadkach oprócz jednej, podana długość maski ma swoistość jest mniejsza lub równa normalnej klasowej długości maski na początku zakresu. Zatem każdy z tych zakresów VLSR jest równoważny jednej lub większej liczbie klasowych sieci. Na przykład 172.16.0.0/12jest równoważny do sieci klasy B 172.16.0.0do 172.31.0.0lub zakresu adresów 172.16.0.0do 172.31.255.255.

Wyjątkiem od tej reguły jest 100.64.0.0/10zakres VLSR, który jest bardziej szczegółowy niż zawierający 100.0.0.0zakres klasy A. W ten sposób 100.0.0.0będzie traktowane jak inne zakresy klasy A, z tym wyjątkiem, że ma otwór na środku 4 194 304 adresów. Prawidłowe adresy w tym zakresie klasy A będą 100.0.0.0do 100.63.255.255i 100.128.0.0do 100.255.255.254łącznie 2 24 - 2 22 - 2 (= 12 582 910) adresów ogółem.

Celem tego wyzwania jest wyprowadzenie wszystkich adresów IPv4 emisji pojedynczej klasy A, B i C, które mogą być prawidłowo przypisane do publicznego hosta internetowego (tj. Z wyłączeniem tych wyszczególnionych powyżej).

  • Nie zostaną podane żadne dane wejściowe i nie należy się ich spodziewać.

  • Dane wyjściowe mogą być w dowolnej formie dogodnej dla Twojego języka, np. Tablica, lista, łańcuch rozdzielany. Adresy muszą być wyprowadzane w standardowym formacie dziesiętnym z kropkami.

  • Kolejność wyjściowa nie ma znaczenia.

  • Wbudowane, które konkretnie podają wymagany zakres adresów, są niedozwolone. Podobnie wszelkie metody dynamicznej kontroli tabeli routingu BGP (lub innego protokołu) dla publicznego Internetu są niedozwolone.

Najniższy będzie 1.0.0.1numer, a najwyższy - numer 223.255.255.254.


Wyzwanie to jest podobne do Wydrukuj wszystkie adresy IPv6 , ale ze względu na ograniczenia powinno wymagać implementacji innej niż trywialna.

Odpowiedzi:


2

PowerShell, 648 641 625 bajtów

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

Edycja 1 - Grałem w golfa wszystkich pozostałych operatorów dwóch potęg, co pozwoliło zaoszczędzić dodatkowe 7 bajtów.
Edycja 2 - Przeniesiono [uint64]rzut do pierwszej deklaracji, $aktóra wyeliminowała pozostałe dwa powtórzenia rzutów, co pozwoliło zaoszczędzić 16 bajtów.

Trzy linie, klasa A / klasa B / klasa C. Pozostawiono jako osobne linie dla czytelności. ;-)

Dwa kluczowe punkty do zrozumienia, co się dzieje:

  • PowerShell ma potęgę dwóch operatorów KB, MB, GB. Na przykład 4KBwróci 4096jako int. Wykorzystujemy to w wielu lokalizacjach, aby ogolić dziesiątki bajtów.
  • [ipaddress]Klasa .NET spróbuje parsować wartość liczbową jako adres IP, przyjmując binarną reprezentację liczby. Używamy tego konstruktora z IPAddressToStringargumentem wyjścia.

Łącząc te dwie rzeczy, możemy traktować adresy IP jak liczby i przechodzić przez nie for()pętlą. Na przykład pierwsza pętla dla podsieci klasy A przechodzi od 16MBdo 2GB-16MBlub od 16777216do 2130706432. Binarna reprezentacja 16777216jest 1000000000000000000000000lub 00000001.00000000.00000000.00000000jeśli podzielimy ją na 8-bitowe fragmenty, abyśmy mogli łatwo zobaczyć, że odpowiada to 1.0.0.0notacji dziesiętnej z kropkami. Podobnie, 2130706432można zapisać jako 01111111000000000000000000000000lub 01111111.00000000.00000000.00000000lub 127.0.0.0. Każdą liczbę całkowitą lub potęgę dwóch liczb całkowitych używanych tutaj można przepisać w ten sposób jako adres IP.

Tak więc dla każdej iteracji pętli konstruujemy if()instrukcję usuwającą wykluczone adresy, mnożąc razem poszczególne instrukcje. Ponieważ pierwsza instrukcja w każdej z nich ifjest liczbą całkowitą (dzięki testowaniu modulo), pozostałe wartości boolowskie są konwertowane na jedną 0lub 1na fałsz / prawda. Jeśli którekolwiek z oświadczeń jest fałszywe, całe mnożenie zwróci się 0i tym samym będzie fałszywe. Dlatego tylko wtedy, gdy wszystkie instrukcje są prawdziwe, wyprowadzimy wynik analizy.

Nieznacznie niepoddany golfowi:

# 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

Partia, 1930 1884 1848 1830 bajtów

@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

Edycja: Zapisano 46 82 bajtów, usuwając niepotrzebne spacje. Zapisano 18 bajtów, używając exit/bzamiast goto:eof.


1
Liczę 1872 bajty. Ty technicznie nie potrzebują @echo off, jak również.
Addison Crump

@FlagAsSpam Prawdopodobnie CR; Notatnik lubi je zapisywać.
Neil

Myślę, że możesz je usunąć, ponieważ liczymy według uniksowych bajtów UTF-8.
Addison Crump
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.