Wyzwanie
Biorąc pod uwagę IPv4 address
w notacji z kropkami-kwadracikami i IPv4 subnet
w notacji CIDR , sprawdź, czy address
jest w subnet
. Podaj wyraźną i spójną wartość, jeśli jest w subnet
, i osobną odrębną i spójną wartość, jeśli nie jest w subnet
. Wartości wyjściowe niekoniecznie muszą być zgodne z prawdą / falsey w twoim języku.
Podstawowy zapis notacji podsieci CIDR
Adresy sieciowe IPv4 mają długość 32 bitów i są podzielone na cztery grupy po 8 bitów dla ułatwienia odczytu. Notacja podsieci CIDR jest maską określonej liczby bitów, zaczynając od lewej strony. Na przykład dla /24
podsieci oznacza to, że 8 najbardziej prawych bitów adresu jest dostępnych w tej podsieci. Zatem dwa adresy, które są oddzielone co najwyżej 255
i mają tę samą maskę podsieci, znajdują się w tej samej podsieci. Zauważ, że w prawidłowym CIDR wszystkie bity hosta (po prawej stronie) są wyłączone (zera).
xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^--- subnet mask ---^ ^-hosts-^
W innym przykładzie /32
podsieć określa, że wszystkie bity są maską podsieci, co zasadniczo oznacza, że dozwolony jest tylko jeden host na /32
.
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^--- subnet mask ---^
Przykłady:
Użycie True
jako „w podsieci” i False
„nie w podsieci” jako danych wyjściowych:
127.0.0.1
127.0.0.0/24
True
127.0.0.55
127.0.0.0/23
True
127.0.1.55
127.0.0.0/23
True
10.4.1.33
10.4.0.0/16
True
255.255.255.255
0.0.0.0/0
True
127.1.2.3
127.0.0.0/24
False
127.1.2.3
127.1.2.1/32
False
10.10.83.255
10.10.84.0/22
False
Zasady i wyjaśnienia
- Ponieważ analiza wejściowa nie jest interesującym punktem tego wyzwania, masz gwarancję uzyskania prawidłowych adresów IPv4 i masek podsieci.
- Dane wejściowe i wyjściowe można podać dowolną dogodną metodą .
- Możesz wydrukować wynik do STDOUT lub zwrócić go jako wynik funkcji. Podaj w swoim zgłoszeniu, jakie wartości może przyjąć wynik.
- Dopuszczalny jest pełny program lub funkcja.
- Standardowe luki są zabronione.
- To jest golf golfowy, więc obowiązują wszystkie zwykłe zasady gry w golfa, a wygrywa najkrótszy kod (w bajtach).
źródło
10.0.0.1/10.0.0.0”/16
?1.255.1.1/8
jest prawidłowym wyrażeniem CIDR , reprezentującym hosta1.255.1.1
w sieci1.0.0.0
za pomocą maski podsieci255.0.0.0
. Jednak wyzwanie wymaga numeru sieci i podsieci, szczególnie w notacji CIDR, która1.255.1.1/8
nie jest prawidłową kombinacją numeru sieci i podsieci.Odpowiedzi:
Python 3 (62 bajty)
Bardzo proste:
źródło
ip_adress
obiekt iip_network
obiekt stanowiąany convenient method
, być może pozwalając Pythonowi wygrać, chyba że język golfowy oparty na Pythonie ma te typy?(host^net)>>(32-mask)
ma tylko 10 bajtów. Ale jest w połowie drogi do zadań nieobejmujących list list lub mapowania funkcji na listę, ponieważ wiele operacji skalarnych można wykonać za pomocą instrukcji 2 lub 3 bajtów, a pętle można zbudować wokół rzeczy w kilku bajtach.C # (kompilator Visual C #) , 250 + 31 = 281 bajtów
Liczba bajtów obejmuje
using System;using System.Linq;
Wypróbuj online!
Napisałem to w JS, jak tylko opublikowano wyzwanie, ale Arnauld pobił mnie do bicia znacznie lepszą odpowiedzią, więc tutaj jest w C #.
Zdecydowanie dużo miejsca na grę w golfa.
Wyjaśnienie:
Funkcja składa się z podfunkcji o nazwie
h
:Ta podfunkcja dzieli adres IP
.
, konwertuje każdą liczbę na ciąg binarny, lewy0
dopełnia każdy ciąg o długości 8 bitów, a następnie konkatenuje ciągi w jeden 32-bitowy ciąg binarny.Odbywa się to natychmiast na miejscu z
a=h(a);
podanym adresem IP.Następnie dzielimy maskę podsieci na adres IP i numer maski za pomocą
c=b.Split('/');
Składnik adresu IP jest również przekazywany przez naszą podfunkcję:
b=h(c[0]);
a numer maski jest analizowany na liczbę całkowitą:var d=int.Parse(c[1]);
Na koniec bierzemy pierwsze
d
bity obu ciągów binarnych (gdzied
jest numerem maski) i porównujemy je:return a.Substring(0,d)==b.Substring(0,d);
źródło
rPad
wbudowane ciągi znaków. pastebin link do zbyt długiego linku TIOPowłoka Linux POSIX (z net-tools / iputils) (34 bajty nie kończące się, 47 bajtów kończące się)
Co najlepiej nadaje się do analizowania masek sieciowych i adresów niż same narzędzia sieciowe? :)
Ostrzeżenie: skrypt może potencjalnie uszkodzić łączność z Internetem, należy zachować ostrożność.
Dane wejściowe: skrypt przyjmuje jako pierwszy argument przetestowany adres IP i testowaną podsieć. jako drugi argument.
Dane wyjściowe: skrypt zwraca prawdziwą wartość (0), jeśli pierwszy argument skryptu należy do podsieci wskazanej w drugim argumencie. W przeciwnym razie nigdy się nie skończy.
Założenia: skrypt musi być uruchamiany jako użytkownik root, w czystym środowisku ( tj. Administrator nie ustawił żadnej innej trasy blackhole, a jeśli uruchomiono poprzednie wystąpienie skryptu, utworzona przez niego trasa blackhole została usunięta ). Skrypt zakłada także „działające połączenie internetowe” ( tzn. Obecna jest poprawna domyślna trasa).
Wyjaśnienie:
Tworzymy trasę blackhole do określonej podsieci. Następnie testujemy łączność z podanym adresem IP za pomocą polecenia ping . Jeśli adres nie należy do podsieci (a ponieważ zakładamy odpowiednio ustawione połączenie internetowe), ping spróbuje wysłać pakiety na ten adres. Pamiętaj, że to, czy ten adres faktycznie odpowiada, nie ma znaczenia, ponieważ ping będzie próbował zawsze. I odwrotnie, jeśli adres należy do podsieci, ping zakończy się niepowodzeniem z ENETUNREACH i zwróci 2, a ponieważ zanegowaliśmy polecenie, skrypt się powiedzie.
Przykład
Sprawdź, czy 5.5.5.5 należy do 8.8.8.0/24
(Oczyść za pomocą
sudo ip route del 8.8.8.0/24
po uruchomieniu polecenia).Sprawdź, czy 5.5.5.5 należy do 5.5.5.0/24:
(Oczyść za pomocą
sudo ip route del 5.5.5.0/24
po uruchomieniu polecenia).Sprawdź, czy 8.8.8.8 należy do 5.5.5.0/24:
(Wyczyść za pomocą
sudo ip route del 5.5.5.0/24
po uruchomieniu polecenia).Wersja 47-bajtowa, jeśli nie zezwalamy na nie kończące się skrypty
Zgodnie z komentarzem @ Grimy, oto wersja, która zawsze kończy się i zwraca 0 (prawda), jeśli adres znajduje się w podsieci, i 1 (fałsz) w przeciwnym razie. Sprawiamy, że ping kończy się
-c1
flagą, która ogranicza liczbę wysłanych pakietów do 1. Jeśli adres odpowiedział, ping zwróci 0, a jeśli nie, ping zwróci 1. Tylko jeśli adres należy do podholowanej podsieci, ping zwróci 2, dlatego testujemy w ostatnim poleceniu.źródło
ping
umarłby od SIGPIPE, gdyby działał ze stdout + stderr podłączonymi do innego programu, a czytnik zamknął potok. I to jest najbardziej prawdopodobny przypadek użycia, ponieważ status wyjścia może być udany w obu przypadkach (jeśli dodamy-c1
opcję pingowania, aby ustawić liczbę). Ale na pewno odczytanie jego wynikuvar=$(/a.sh)
nie powiedzie się; potrzebujesz czytnika, który zatrzyma się po podjęciu decyzji, zamiast czytać cały wynik, a następnie patrzeć na niego.ping
zakończą się one w mniej niż, powiedzmy, jednej sekundzie w przypadku czarnego adresu). Dodałem wersję końcową dla dodatkowych 13 bajtów! :)JavaScript (ES6), 82 bajty
Pobiera dane wejściowe jako
(address)(subnet)
. Zwraca wartość logiczną.Wypróbuj online!
źródło
PHP ,
1019288 bajtów-13 bajtów od @gwaugh
Wypróbuj online!
źródło
function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
strtok()
. Twój jest o 4 bajty krótszy niż moja bardzo podobna odpowiedź poniżej. Rekwizyty!PowerPC / PPC64 C,
116114 bajtów(Testowany na Ubuntu 18.04 x86_64 przy użyciu powerpc64-linux-gnu-gcc -static i qemu-user.)
Program przyjmuje dwa wiersze na standardowym wejściu i jako kod wyjścia zwraca 1, jeśli adres jest zgodny, i 0, jeśli nie. (Tak więc zależy to od specyfikacji, która nie wymaga prawdziwej wartości dla dopasowania i wartości falsey dla niedopasowania.) Pamiętaj, że jeśli biegniesz interaktywnie, będziesz musiał zasygnalizować EOF (
^D
) trzy razy po wejściu do drugiej linii.Polega to na tym, że PowerPC jest big-endian, a także na tej platformie zwracającej 0 za przesunięcie w prawo 32-bitowej wartości bez znaku o 32. Czyta oktety do wartości bez znaku jeden po drugim, wraz z długością maski sieci w innym bajcie ; następnie pobiera xor dwóch niepodpisanych 32-bitowych adresów i przenosi niepotrzebne bity. Wreszcie ma zastosowanie
!
do spełnienia wymogu zwrotu tylko dwóch różnych wartości.Uwaga: To może być możliwe, aby zgolić dwa bajty zastępując
u+3
zep
i wymagające kompilacja-O0
. Ale to żyje bardziej niebezpiecznie, niż mi zależy.Dziękujemy Peterowi Cordesowi za inspirację do tego rozwiązania.
Bardziej przenośne C,
186171167 bajtówTutaj zachowam bardziej przenośną wersję, która ma 167 bajtów.
Ten program pobiera dwa wiersze na standardowym wejściu i zwraca kod wyjścia 1, jeśli adres znajduje się w podsieci, i 0, jeśli nie jest. (Tak więc zależy to od specyfikacji, która nie wymaga prawdziwej wartości dla dopasowań i wartości falsey dla niezgodności.)
Podział podstawowego wyrażenia:
a^e
,b^f
,c^g
,d^h
Oblicza XOR adresu i maskę bajt bajcie.(((a^e)<<8|b^f)<<8|c^g)<<8|d^h
następnie łączy je w jedną 32-bitową wartość bez znaku metodą Hornera....>>32-n
następnie odsuwa bity różnicy xor, które nie są istotne dla maski podsieci (pamiętając, że-
ma wyższy priorytet w C niż<<
)~0U<<32
daje niezdefiniowane zachowanie, zakładając, żeunsigned
ma on 32 bity (czyli na praktycznie wszystkich obecnych platformach). Z drugiej strony, jeśli n = 0, to dowolny adres będzie zgodny, więcn&&...
da poprawny wynik (wykorzystując zachowanie zwarcia&&
).!
do wyjścia 0 lub 1.-15 bajtów ze względu na komentarze sufitcatcat i AdmBorkBork
-4 bajty z powodu komentarza Petera Cordesa
źródło
unsigned
. np. zchar*p=&a
wtedyp++,p++,p++,...
lubp--,...
jako argumenty scanf. Ciąg formatujący musiałby jednak być"%hhu.%hhu..."
, więc jest to znaczący kompromis między tym dodatkowym rozmiarem a deklarowaniem mniejszej liczby zmiennych i możliwością wykonania(a^b)>>(32-count)
Stax , 22 bajty
Uruchom i debuguj
Pobiera parametry wejściowe oddzielone spacją na standardowym wejściu.
Rozpakowane, niepolowane i skomentowane, wygląda to tak.
Uruchom ten
źródło
x86-64 funkcja kodu maszynowego,
5348 bajtówdziennik zmian:
jz
w trakcie zmiany zamiast używać zmiany 64-bitowej do obsługi>>(32-0)
specjalnego przypadku.setnz al
.(Zobacz także odpowiedź na 32-bitowy kod maszynowy Daniela Scheplera opartą na tym , która następnie ewoluowała, aby użyć innych pomysłów, które mieliśmy. moją najnowszą wersję tego na dole tej odpowiedzi).
Zwraca ZF = 0 dla hosta nie podsieci, ZF = 1 dla podsieci, dzięki czemu można rozgałęzić wynik za pomocą
je host_matches_subnet
Można wywoływać za pomocą konwencji wywoływania Systemu V x86-64 jako
bool not_in_subnet(int dummy_rdi, const char *input_rsi);
przypadku dodawaniasetnz al
.Łańcuch wejściowy zawiera zarówno host, jak i sieć, oddzielone dokładnie 1 cyfrą. Pamięć po końcu szerokości CIDR musi zawierać co najmniej 3 bajty niebędące cyframi przed końcem strony. (W większości przypadków nie powinno to stanowić problemu, na przykład dla argumentu cmdline). Wersja 32-bitowa Daniela nie ma tego ograniczenia.
3 razy uruchamiamy tę samą pętlę parsowania quad z kropkami, uzyskując dwa adresy IPv4 i otrzymując
/mask
jako liczbę całkowitą w wysokim bajcie dwordu. (To dlatego musi istnieć czytelna pamięć po/mask
, ale nie ma znaczenia, czy są cyfry ASCII.)Robimy,
(host ^ subnet) >> (32-mask)
aby przesunąć bity hosta (te, które mogą się nie zgadzać), pozostawiając jedynie różnicę między podsiecią a hostem. Aby rozwiązać/0
specjalny przypadek, w którym musimy przesunąć o 32, przeskakujemy zmianę przy liczeniu = 0. (neg cl
ustawia ZF, który możemy rozgałęzić i pozostawić jako wartość zwracaną, jeśli nie przesuniemy). Zauważ, że32-mask mod 32 = -mask
przesunięcia skalarne x86 maskują ich liczbę przez& 31
lub& 63
.(nie zaktualizowany do najnowszej wersji) Wypróbuj online!
w tym
_start
wywoływanie goargv[1]
i zwracanie statusu wyjścia.Działa dobrze, jeśli podasz argument wiersza poleceń zawierający znak nowej linii zamiast spacji. Ale to musi być zamiast , nie tak dobrze.
x86 32-bitowa funkcja kodu maszynowego, 38 bajtów
Wykonaj 9 liczb całkowitych -> uint8_t parsuje i „wypychasz” je na stos, gdzie wyrzucamy je jako dwory lub używamy ostatniego jeszcze w CL. W ogóle unika czytania poza końcem łańcucha.
Ponadto
dec
ma tylko 1 bajt w trybie 32-bitowym.Testuj dzwoniącego
źródło
cmp/jcc
, o którym wspomniałeś, zrobiłeś coś podobnegoxor edx,edx;neg cl;cmovz eax,edx;shr eax,cl
- a może masz już gdzieś wartość 0. (A potem nie potrzebowałbyśsub cl,32
instrukcji.)edi
powinna wynosić 0, gdy pętla wychodzi, więcxor eax,edx;neg cl;cmovz eax,edi;shr eax,cl
powinna działać.cmove eax,edi
ma 3 bajty, co jest wymywaniem usuniętym,sub cl,32
a następnieshr cl,eax
zapisuje jeden bajt ponad,shr cl,rax
a 32-bitowydec edi
zapisuje jeden bajt ponad 64-bitdec edi
. Mój zestaw następnie daje.byte 0x33
(w składni binutils GNU) = 51 dlain_subnet.size
.shr eax,cl
, w porównaniu zeshr %cl, %eax
składnią AT&T, twój ostatni komentarz odwrócił to.) Trochę ciężko jest zaktualizować odpowiedzi na kod maszynowy (i przenieść port_start
wywołujący i ponownie opisać konwencję wywoływania dla trybu 32-bitowego. .), więc mogę się nie obejść. Czuję się dziś leniwy. >. <edi
zapisu, zapisu danych wyjściowych itp., W efekcie zaoszczędziłem 2 bajty w sieci. (Przynajmniej raz zdałem sobie sprawę, żepush ecx;push ecx;push ecx
był krótszy niżsub esp,12
; i wydawało mi się, że to pranie, czy przygotowałem wcześniejedi
i użyłem,std;stosb;cld
czy też właśnie przechowałemdec edi;mov [edi],al
.Galaretka , 23 bajty
Wypróbuj online!
Łącze monadyczne, które bierze adres i podsieć oddzielone ukośnikiem i zwraca 1 dla wartości true i 0 dla wartości false.
Dzięki @gwaugh za wskazanie błędu w oryginale - nie udało się zapewnić, aby lista binarna miała 32 długości.
źródło
Perl 5
-Mbigint -MSocket=:all -p
, 72 bajtówWypróbuj online!
źródło
05AB1E , 21 bajtów
Zajmuje podsieć przed adresem.
Wypróbuj online lub sprawdź wszystkie przypadki testowe .
Wyjaśnienie:
źródło
R 120 bajtów
funkcja - wkleiłem „.32” do pierwszego terminu
w=function(a,b){f=function(x)as.double(el(strsplit(x,"[./]")));t=f(paste0(a,".32"))-f(b);sum(t[-5]*c(256^(3:0)))<2^t[5]}
i dla zabawy:
require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]
czyli 56 bajtów
źródło
PHP ,
7573, 71 bajtówRozwidlenie odpowiedzi @Luis felipe De jesus Munoz , jako samodzielne pobieranie danych z linii poleceń. Wyjścia
'1'
dla Truthy,''
(pusty string) dla Fasley.Wypróbuj online!
-2 bajty pożyczanie małej sztuczki @Christoph
strtok()
. Jego odpowiedź jest jednak jeszcze krótsza!źródło
funkcja montażu x86,
4943 bajtyJest to głównie publikowane w celu spełnienia prośby Petera Cordesa o poprawioną wersję, którą stworzyłem. Prawdopodobnie może odejść raz / jeśli uwzględni to w swojej odpowiedzi.
Ta funkcja oczekuje
esi
na ciąg wejściowy, w którym adres i części podsieci są oddzielone spacją lub znakiem nowego wiersza, a zwracana wartość jest w flagi ZF (która z definicji ma tylko dwie możliwe wartości).Część otoki Linux x86:
-6 bajtów z powodu sugestii Petera Cordesa, aby zwrócić wartość w ZF.
źródło
xor edx,edx
i zastępująccmovz eax,edx
gojz .nonzero; xor eax,eax; .nonzero:
.cmovz
nadal wygrywa, jeśli mamy konwencję wywoływaniaebx=0
.jz
nadshr
do setz lub ret? Możemy zamienićsetnz
sięsetz
i powrócić1
na mecz, czy to pomaga. Lub nawet powiedzieć, że naszą wartością zwrotną jest ZF. Powinienem był to zrobić w mojej odpowiedzi. (Ale nie sądzę, abyśmy mogli uzasadnić wymaganie od osoby dzwoniącej utworzenia stałych, npebx=0
.. Moja odpowiedź na temat wskazówek dotyczących gry w golfa w kodzie maszynowym x86 / x64 dowodzi, że zbyt daleko posunęłaby się konwencja wywoływania niestandardowego.cut
usunąć niektóre kolumny z wydruki NASMa ponieważ wszystkie moje instrukcje są krótkie:nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Użyłem także mov zamiast movzx w moim programie_start
wywołującym, ponieważ status wyjścia pochodzi z małego bajtu argumentu argsys_exit()
. Jądro ignoruje wyższe bajty.setnz al
pocall in_subnet
w opakowaniu.call
/je
, zamiast drukowania lub dalszego przekazywania wyniku. Jak wskazałem w „poradach”, niektóre konwencje wywołań systemowych już to robią w prawdziwym życiu (zwykle z CF = błąd).Java
215 211 207 202 200 199 198 190180 bajtówWyjścia
true
dla prawdy ifalse
fałszu.Uwaga: Używa
long
zamiastint
potencjalnego przesunięcia w prawo o 32.Wypróbuj online!
Zaoszczędzono 1 bajt dzięki pułapce cat
Zaoszczędź 10 bajtów dzięki Peterowi Cordesowi
źródło
host ^ net
aby przesunąć bity, które chcesz usunąć, zamiast tworzyć maskę. Ale myślę, że Java potrzebuje tam porównania, aby utworzyć wartość logiczną z liczby całkowitej. Może a!
, ponieważ nie ma znaczenia, które z prawd czy fałszów produkujesz dla których wyników. (Poprosiłem PO o wyjaśnienie, czy zamierzają wykluczyć 0 / niezerowe, i powiedzieli, że tak, byli świadomi konsekwencji tego sformułowania:long
to, że stracę trochę bajtów, ale nadrabiam to, mogąc usunąć trójskładnik i wykonać XOR, jak sugerujesz. Sprawdzam, co jeszcze mogęWęgiel drzewny , 36 bajtów
Wypróbuj online! Link jest do pełnej wersji kodu. Traktuje podsieć jako pierwszy parametr i wyświetla dane wyjściowe
-
tylko wtedy, gdy adres znajduje się w podsieci. Wyjaśnienie:Podziel podsieć
/
.Zdejmij maskę i rzuć ją na liczbę całkowitą.
Wciśnij adres do tablicy.
Podziel oba adresy
.
, przekonwertuj je na liczby całkowite, zinterpretuj jako bazę 256 i odrzuć zamaskowane bity.Porównaj dwie wartości.
źródło
Japt , 26 bajtów
Spróbuj
-3 bajty dzięki @Shaggy!
Dane wejściowe to tablica z 2 elementami
[address, subnet]
. Transponowane JS poniżej:źródło
++
.g
Denerwuje mnie potrzeba przecinka w metodzie; w ogóle nie mogę tego rozwiązać. Przynajmniej nie taki, który uratuje ci bajt.C # (interaktywny kompilator Visual C #) , 187 bajtów
Mogę zdecydowanie pograć w golfa bardziej.
Wypróbuj online!
źródło
C # (interaktywny kompilator Visual C #) , 134 bajty
Wypróbuj online!
Instrukcja LINQ, która przyjmuje 2-elementową tablicę ciągów jako dane wejściowe
[address, subnet]
formacie.Każdy kropkowany quad jest przetwarzany na 32 bity długości za pomocą manipulacji bitami. Bity są przesunięte w prawo o rozmiar podsieci, a elementy są porównywane pod kątem równości.
W chwili opublikowania tej odpowiedzi było kilka odpowiedzi w języku C #, ale żadna nie korzystała z czystej manipulacji bitami.
źródło
Rubinowy (48 bajtów)
źródło
====