Adres IP czy nie?

25

Twoje narzędzie do skanowania sieciowego jest denerwująco wybredne w zakresie wprowadzania danych i natychmiast ulega awarii, jeśli podasz mu adres IPv4, który zawiera nieprawidłowe znaki lub nie jest poprawnie sformatowany.

Adres IPv4 to 32-bitowy adres numeryczny zapisany jako cztery liczby oddzielone kropkami. Każda liczba może wynosić od zera do 255 .

Musimy napisać narzędzie, aby wstępnie sprawdzić poprawność danych wejściowych, aby uniknąć tych awarii, a nasze konkretne narzędzie jest wybredne: prawidłowy format będzie wyglądał tak, a.b.c.dgdzie a, b, cid:

  • Może być 0liczbą naturalną lub bez zer wiodących .
  • Powinien wynosić od 0 do 255 (włącznie).
  • Gdyby nie zawierają specjalne symbole, takie jak +, -, ,i innych.
  • Powinien być dziesiętny (podstawa 10)

Dane wejściowe : ciąg

Dane wyjściowe : wartość Truthy lub Falsey (akceptowane są również dowolne wartości)

Przypadki testowe :

Input            |  Output  |  Reason
                 |          |
- 1.160.10.240   |  true    |
- 192.001.32.47  |  false   |  (leading zeros present)
- 1.2.3.         |  false   |  (only three digits)
- 1.2.3          |  false   |  (only three digits)
- 0.00.10.255    |  false   |  (leading zeros present)
- 1.2.$.4        |  false   |  (only three digits and a special symbol present)
- 255.160.0.34   |  true    |
- .1.1.1         |  false   |  (only three digits)
- 1..1.1.1       |  false   |  (more than three periods)
- 1.1.1.-0       |  false   |  (special symbol present)
- .1.1.+1        |  false   |  (special symbol present)
- 1 1 1 1        |  false   |  (no periods)
- 1              |  false   |  (only one digit)
- 10.300.4.0     |  false   |  (value over 255)
- 10.4F.10.99    |  false   |  (invalid characters)
- fruit loops    |  false   |  (umm...)
- 1.2.3.4.5      |  false   |  (too many periods/numbers)
- 0.0.0.0        |  true    |
- 0.0 0.0.       |  false   |  (periods misplaced)
- 1.23..4        |  false   |  (a typo of 1.2.3.4)
- 1:1:1:1:1:1:1:1|  false   |  (an IPv6 address, not IPv4)

To jest , więc wygra najmniej bajtów!

Uwaga dla użytkowników - jeśli chcesz dodać więcej przypadków testowych, jesteś mile widziany (sugerując edycję). Ale upewnij się, że przypadki testowe się nie powtarzają! Dzięki

rv7
źródło
10
Zaproponuj testami: 1.1.1.1.1, 1.1.1.1., .1.1.1, 1..1.1, 1..1.1.1, 1.1.1.0, 1.1.1.-0, 1.1.1.+1, 1.1.1.1E1, 1.1.1.256, 1.1.1.0x1, 255.255.255.255, 0.0.0.0, 'or 1=1--, <empty string>, 1 1 1 1, 1,1,1,1.
tsh
5
Zaproponuj dodanie przypadków testowych „1.2.3.4.5” (aby wykluczyć zbyt długie adresy IP) i „999.0.0.0” (aby wykluczyć zbyt duże adresy IP).
Triggernometry
5
Być może nieco wybredna, ale prawdopodobnie powinieneś odwoływać się do „adresów IPv4” zamiast „adresów IP” - lub przynajmniej wspomnieć gdzieś, że masz na myśli tylko adresy IPv4 - w przeciwnym razie 1234: 5678 :: 1 powinien być prawidłowym adresem IP (podczas gdy z opisu jasno wynika, że ​​nie jest to zamierzone :)
psmears
3
@Criggie Założeniem nie jest faktycznie sprawdzić wszystkie realne zasady IP4 (jak te, które Ci wymienionych), to w celu zapewnienia, że ciąg wejściowy nie psuje jakiś inny (prawdopodobnie źle napisane) aplikację, która pozwala tylko na wejście w bardzo specyficznej formie . Nie zamierzamy również zmieniać zasad wyzwania, które ma już ponad 30 odpowiedzi.
BradC,
2
@ Criggie Warto zauważyć, że RFC deklaruje, że „Adresy mają ustaloną długość czterech oktetów”. Myślę, że przypadki skrajne, o których wspominasz, są bardziej wyspecjalizowane niż to wyzwanie.
Poke

Odpowiedzi:

26

Kod maszynowy X86_64: 18 16 bajtów

Edycja: Ta odpowiedź nie działa, jak

  1. Korzystam inet_ptonze standardowych bibliotek C, co oznacza, że ​​potrzebuję zewnętrznego. Nie uwzględniłem jednak zewnętrznego w mojej liczbie bajtów.
  2. W rezultacie użyłem czerwonej strefy jako rzeczywistego adresu, ale wywołałem funkcję, która również mogła użyć czerwonej strefy. Na szczęście nie ma go na moim komputerze, ale może go używać jakaś dziwna standardowa biblioteka, która może powodować niezdefiniowane zachowanie.

I tak, cała ta sprawa jest wykonywana przez już napisaną funkcję

W każdym razie mam to: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Montaż:

section .text
    extern inet_pton
    global ipIsValid

ipIsValid:
    mov rsi, rdi
    ;mov rdi, 2 ; change to 10 for ipv6
    push 2
    pop rdi ; thank you peter
    lea rdx, [rsp - 128]
    jmp inet_pton

Wyjaśnienie:

Spójrz na inet_pton(3). Pobiera ciąg adresu IP i umieszcza go w buforze, którego można używać struct sockaddr. Wymaga 3 argumentów: rodziny adresów ( AF_INET(ipv4), 2 lub AF_INET6(ipv6), 10), ciągu adresu ip i wskaźnika na wynik. Zwraca 1 w przypadku sukcesu, 0 na nieprawidłowy adres, lub -1 gdy rodzina nie jest ani adres AF_INETlub AF_INET6(co nigdy nie nastąpi, bo jestem przechodzącej stałej do niego).

Więc po prostu przenoszę ciąg do rejestru dla drugiego argumentu, ustawiam pierwszy rejestr na 2 i ustawiam trzeci rejestr na czerwoną strefę (128 bajtów poniżej wskaźnika stosu), ponieważ nie dbam o wynik. Wtedy mogę po prostu jmpsię inet_ptoni pozwól, że powrót do rozmówcy prosto!

Uruchomiłem ten szybki program testowy, aby przetestować twoje przypadki:

#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/ip.h>

extern int ipIsValid(char *);

int main(){
    char *addresses[] = {
        "1.160.10.240",
        "192.001.32.47",
        "1.2.3.",
        "1.2.3",
        "0.00.10.255",
        "1.2.$.4",
        "255.160.0.34",
        ".1.1.1",
        "1..1.1.1",
        "1.1.1.-0",
        ".1.1.+1",
        "1 1 1 1",
        "1",
        "10.300.4.0",
        "10.4F.10.99",
        "fruit loops",
        "1.2.3.4.5",
        NULL
    };

    for(size_t i = 0; addresses[i] != NULL; ++i){
        printf("Address %s:\t%s\n", addresses[i],
            ipIsValid(addresses[i]) ? "true" : "false");
    }
    return 0;
}

Zbierz nasm -felf64 assembly.asm, skompiluj z gcc -no-pie test.c assembly.o, a otrzymasz:

Address 1.160.10.240:   true
Address 192.001.32.47:  false
Address 1.2.3.: false
Address 1.2.3:  false
Address 0.00.10.255:    false
Address 1.2.$.4:    false
Address 255.160.0.34:   true
Address .1.1.1: false
Address 1..1.1.1:   false
Address 1.1.1.-0:   false
Address .1.1.+1:    false
Address 1 1 1 1:    false
Address 1:  false
Address 10.300.4.0: false
Address 10.4F.10.99:    false
Address fruit loops:    false
Address 1.2.3.4.5:  false

Mógłbym to znacznie zmniejszyć, jeśli dzwoniący miałby przejść AF_INETlub przejść AF_INET6do funkcji

użytkownik233009
źródło
4
Uwielbiam to, że zrobiłeś to w asm. A fakt, że wyjaśniłeś to tym, którzy mogą go nie rozumieć (a także kod testowy) jest jeszcze lepszy. Co nie znaczy, że mógłbym to zrobić w asm; minęło zbyt wiele lat, ale pamiętam wystarczająco dobrze, aby zobaczyć dokładnie to, co mówi (a więc i proces) twoje wyjaśnienie. Dobra robota.
Pryftan
4
e9 00 00 00 00jest, a jmp near $+5nie jmp inet_pton. Jeśli podasz opcode, powinieneś dołączyć inet_ptonczęść zawierającą , a nie pozostawić puste
l4m2
1
15 bajtów-TIO 32bit x86
Logern
3
w tytule odpowiedzi należy umieścić zewnętrzną, ponieważ program tego wymaga i nie jest dostępny na wszystkich platformach.
qwr
1
„mov rdi, 2” może być „push 2 / pop rdi” dla -2 bajtów. Zauważ też, że demontaż jest nieprawidłowy lub kod jest nieprawidłowy. Może to być „mov edi” (nie rdi) lub brakuje prefiksu.
Peter Ferrie
13

Java (JDK) , 63 bajty

s->("."+s).matches("(\\.(25[0-5]|(2[0-4]|1\\d|[1-9])?\\d)){4}")

Wypróbuj online!

Kredyty

Olivier Grégoire
źródło
Zapomniałeś usunąć dolnego średnika. ;) I mogę sprawdzić, czy działa dla wszystkich przypadków testowych, w tym w komentarzach. Zobaczę, czy zobaczę kilka rzeczy do gry w golfa.
Kevin Cruijssen
3
Nie powiodło się.1.2.3.4
l4m2
Czy wolno używać wartości logicznej, gdy jawnie wymagają 0/1?
l4m2
1
@ l4m2 Pierwotne pytanie było ważne / nieprawidłowe. Zakładam więc, że dowolna wartość true / falsey jest tutaj akceptowalna.
Kevin Cruijssen
Output: 0 or 1a Java nie ma auto bool-> int
l4m2
12

JavaScript (Node.js) , 43 bajty

x=>x.split`.`.map(t=>[t&255]==t&&[])==`,,,`

Wypróbuj online!

JavaScript (Node.js) , 46 bajtów

x=>x.split`.`.every(t=>k--&&[t&255]==t,k=4)*!k

Wypróbuj online!

wykorzystał część Arnaulda

JavaScript (Node.js) , 54 53 51 bajtów

x=>x.split`.`.every(t=>k--*0+t<256&[~~t]==t,k=4)*!k

Wypróbuj online!

-2B dla 0+t<256, -1B od Patricka Stephansena, + 1B, aby uniknąć wkładu1.1.1.1e-80

Rozwiązanie RegExp 58 54 bajtów

s=>/^((2(?!5?[6-9])|1|(?!0\d))\d\d?\.?\b){4}$/.test(s)

Dziękujemy Deadcode za 3 bajty

l4m2
źródło
Dodałem kilka przypadków testowych!
rv7
To daje prawdę 0.0.0.0. Wszystko inne wydaje się działać dobrze.
Kevin Cruijssen
1
@KevinCruijssen 0.0.0.0jest tutaj prawdziwy. Tylko dlaczego zastrzyk SQL jest tutaj?
l4m2
Ach, czekaj, źle interpretuję zdanie w opisie wyzwania. 0.0.0.0jest rzeczywiście prawdą. To też pomoże mojej odpowiedzi .. (A co masz na myśli przez zastrzyk SQL?: S Link jest do TIO ze WSZYSTKIMI testami.)
Kevin Cruijssen
1
@ l4m2 Dodałem go, ponieważ potrzebujemy testów, które nawet nie wyglądają jak adres IP.
tsh
11

PHP , 39 36 bajtów

<?=+!!filter_var($argv[1],275,5**9);

Wypróbuj online!

275 przypomina stałą FILTER_VALIDATE_IP

5 ** 9 jest używane zamiast stałej FILTER_FLAG_IPV4. Jest to wystarczające, ponieważ 5**9 & FILTER_FLAG_IPV4jest prawdą, co dokładnie robi PHP w tle, jak zauważył Benoit Esnard.

Tu filter_varzwraca pierwszy argument, czy jest to prawidłowy adres IPv4 lub false, jeśli tak nie jest. Dzięki +!!produkujemy dane wyjściowe wymagane przez wyzwanie.

oktupol
źródło
3
Używanie 5**9zamiast 1048576zapisywania 3 bajtów tutaj: PHP używa &do testowania flag IPv4 / IPv6 , więc dowolna liczba między 1048576 a 2097151 jest poprawna.
Benoit Esnard
Niniejszym głosuję poniżej za odpowiedź na to, że jesteś (w zasadzie) moją odpowiedzią: codegolf.stackexchange.com/a/174470/14732, która została napisana o 22.10.2018 09: 17: 34UTC, a twoja została napisana 22.10.2018 09: 21: 55UTC. Nawet jeśli cofnę optymalizację 1-bajtową podaną przez @BenoitEsnard, moja odpowiedź jest dokładnie taka sama jak twoja pod względem funkcjonalności.
Ismael Miguel
2
Muszę przeprosić, nie widziałem waszej odpowiedzi, chociaż w czasie jej pisania nie otrzymałem odpowiedzi w PHP na to pytanie (jak powiedziałeś, różnica czasu jest mniejsza niż pięć minut).
oktupol
Wiem i rozumiem to. Dopiero teraz zauważyłem twój. Mogę wycofać moje, a ty utrzymasz optymalizację. Ale nie wiem, czy dzięki temu odpowiedź będzie wystarczająco inna od siebie.
Ismael Miguel
17
@ IsmaelMiguel Nie oddałbym komuś głosu za to, jeśli jest prawdopodobne, że twojego nie było tam, kiedy zaczęli. Z 5-minutową różnicą nie tylko jest to prawdopodobne, ale prawie na pewno tak jest, co widać nawet bez tego, że autor sam to powiedział.
Duncan X Simpson
11

PHP, 36 bajtów

echo(ip2long($argv[1])===false?0:1);

ip2longjest dobrze znaną funkcją wbudowaną .

rexkogitans
źródło
3
29 bajtów
nwellnhof,
Wydaje się, że korzysta z nieudokumentowanych funkcji obecnych w nowszych wersjach (przypuszczam, że pochodzi z PHP7 +). Pamiętaj, że w PHP 4 i 5 akceptuje to niepełne adresy IP.
Ismael Miguel
27 bajtów
Mark
1
To da sukces, jeśli podasz mu liczbę całkowitą, taką jak 1, 2 itd. Nie myśl, że powinna. A także, jeśli podasz mu coś jako 100.100.100
nl-x
10

Perl 6 , 22 21 20 bajtów

-1 bajt dzięki Philowi ​​H.

{?/^@(^256)**4%\.$/}

Wypróbuj online!

Wyjaśnienie

{                  }  # Anonymous Block
  /               /   # Regex match
   ^             $    # Anchor to start/end
    @(    )           # Interpolate
      ^256            #   range 0..255,
                      #   effectively like (0|1|2|...|255)
           **4        # Repeated four times
              %\.     # Separated by dot
 ?                    # Convert match result to Bool
nwellnhof
źródło
3
Człowieku, muszę poświęcić więcej czasu na zastanawianie się nad wyrażeniami regularnymi Perla 6. Nie miałem żadnego %modyfikatora. Zastanawiam się, czy próbuje sprawdzić wszystkie 256**4możliwości?
Jo King,
1
Zamiast tego <{^256}>możesz po prostu przekonwertować zakres na tablicę @(^256)dla -1 znaków TIO . Zmieniając blok kodu na tablicę, staje się on niezwykle szybki (0,4 zamiast> 30).
Phil H
@PhilH Cool, dzięki. Próbowałem, $(^256)ale teraz zdaję sobie sprawę, dlaczego to nie zadziałało.
nwellnhof
9

05AB1E , 26 24 23 22 23 bajtów

'.¡©g4Q₅Ý®å`®1šDïþJsJQP

-1 bajt dzięki @Emigna .
+1 bajt dla przypadku testowego 1.1.1.1E1naprawienia błędu niepoprawnie zwracającego prawdziwy wynik.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

'.¡              '# Split the (implicit) input by "."
   ©              # Save it in the register (without popping)
    g4Q           # Check that there are exactly 4 numbers
    ₅Ý®å          # Check for each of the numbers that they are in the range [0,255],
        `         # and push the result for each number separated onto the stack
    ®1šDïþJsJQ    # Check that each number does NOT start with a "0" (excluding 0s itself),
                  # and that they consist of digits only
              P   # Check if all values on the stack are truthy (and output implicitly)
Kevin Cruijssen
źródło
1
Powinieneś być w stanie użyć Āzamiast<d
Emigna
@MagicOctopusUrn Obawiam się, że nie powiedzie się 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, i 0.00.10.255. (PS: Naprawiłem 1.1.1.1E1, dodając þopcję łączenia i wyrównywania).
Kevin Cruijssen
W porządku, pomyślałem, że coś przeoczyłem.
Magic Octopus Urn
@MagicOctopusUrn Głównym problemem jest 05AB1E widzenie liczb z wiodącymi zerami równymi zerom, nawet jako ciąg znaków. Dlatego używam DïþJsJQsprawdzić, gdzie ïoddanych do int usunąć wiodące 0s, a þtylko pozostawia cyfry usuwając takie rzeczy E, -itp :) jest dla przypadku testowego 0.00.10.255, ponieważ 00010255i 0010255byłaby równa.
Kevin Cruijssen
Tak, przeszedłem przez ten sam nonsens, ale odwrócenie wszystkich liczb działało całkiem dobrze, z wyjątkiem tych przypadków. Interesujące, gdy funkcje korzystne dla niektórych problemów stają się dla innych prawie podobne do błędów.
Magic Octopus Urn
6

PowerShell, 59 51 49 bajtów

-8 bajtów, dzięki @AdmBorkBork

-2 bajty truelub falsedozwolone przez autora

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}

Skrypt testowy:

$f = {

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}

}

@(
    ,("1.160.10.240" , $true)
    ,("192.001.32.47" , $false)
    ,("1.2.3." , $false)
    ,("1.2.3" , $false)
    ,("0.00.10.255" , $false)
    ,("192.168.1.1" , $true)
    ,("1.2.$.4" , $false)
    ,("255.160.0.34" , $true)
    ,(".1.1.1" , $false)
    ,("1..1.1.1" , $false)
    ,("1.1.1.-0" , $false)
    ,("1.1.1.+1" , $false)
    ,("1 1 1 1" , $false)
    ,("1"            ,$false)
    ,("10.300.4.0"   ,$false)
    ,("10.4F.10.99"  ,$false)
    ,("fruit loops"  ,$false)
    ,("1.2.3.4.5"    ,$false)

) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result : $s"
}

Wydajność:

True: True : 1.160.10.240
True: False : 192.001.32.47
True: False : 1.2.3.
True: False : 1.2.3
True: False : 0.00.10.255
True: True : 192.168.1.1
True: False : 1.2.$.4
True: True : 255.160.0.34
True: False : .1.1.1
True: False : 1..1.1.1
True: False : 1.1.1.-0
True: False : 1.1.1.+1
True: False : 1 1 1 1
True: False : 1
True: False : 10.300.4.0
True: False : 10.4F.10.99
True: False : fruit loops
True: False : 1.2.3.4.5

Wyjaśnienie:

Skrypt próbuje przeanalizować ciąg argumentu, aby utworzyć obiekt .NET, adres IP .

  • zwraca, $truejeśli został objectutworzony, a ciąg argumentu jest równy reprezentacji ciągu object(znormalizowanego adresu przez object.toString())
  • w $falseprzeciwnym razie zwróć

PowerShell, 59 56 54 bajtów, „nie używaj alternatywy .NET lib”

-3 bajty truelub falsedozwolone przez autora

-2 bajty, dzięki @ Deadcode dla fajnego wyrażenia regularnego .

".$args"-match'^(\.(2(?!5?[6-9])|1|(?!0\B))\d\d?){4}$'

Wypróbuj online!

Dzięki @ Olivier Grégoire za oryginalne wyrażenie regularne.

mazzy
źródło
1
Nie powinieneś dzwonić, |% t*gponieważ PowerShell automatycznie rzuci prawą stronę -eqjako ciąg, ponieważ lewa strona jest ciągiem. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork
Możesz wyciąć 2 bajty z wersji „nie używaj biblioteki .NET lib”, używając mojego wyrażenia regularnego (dostosowanego do sztuczki wstawiania kropki, która oczywiście nie może być w mojej wersji, ponieważ jest to czysta wyrażenie regularne): tio.run/…
Deadcode
5

C (gcc) / POSIX, 26 bajtów

f(s){s=inet_pton(2,s,&s);}

Wypróbuj online!

Działa jako 64-bitowy kod w TIO, ale prawdopodobnie wymaga tego sizeof(int) == sizeof(char*)na innych platformach.

nwellnhof
źródło
@TobySpeight Tak, jeśli używasz x86, prawdopodobnie powinieneś spróbować w trybie 32-bitowym ( -m32).
nwellnhof
Dostałem to do pracy, podając sjako char*(nie ma tutaj dostępu do systemu ILP32) i tak, mieszałem się inet_aton().
Toby Speight
5

PHP 7+, 37 35 32 bajty

Korzysta z wbudowanej funkcji filter_var, aby sprawdzić, czy jest to adres IPv4 .

Aby zadziałało, musisz przekazać klucz inad żądaniem GET.

<?=filter_var($_GET[i],275,5**9);

Nie będzie generować niczego (dla falsywyniku) ani adresu IP (dla truthywyniku), w zależności od wyniku.

Możesz to wypróbować na: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Wykorzystuje to bezpośrednio następujące wartości:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (który ma wymagany bit jako „1”, dla 1048576)

Dziękuję Benoit Esnard za tę wskazówkę, która pozwoliła mi zaoszczędzić 1 bajt!

Dziękuję Tytusowi za przypomnienie mi o zmianach w wyzwaniu.


Sprawdziłem użycie tej funkcji ip2long, ale działa ona z niepełnymi adresami IP.

Niepełne adresy IPv4 są uważane za nieprawidłowe w tym wyzwaniu.

Gdyby były dozwolone, byłby to końcowy kod (tylko dla PHP 5.2.10):

<?=ip2long($_GET[i]);

Obecnie w dokumentacji nie jest wyraźnie zaznaczone, że przestanie to działać (po przejściu niekompletnego adresu IP) z nowszymi wersjami PHP.

Po testach potwierdzono, że tak było.

Dzięki nwellnhof za wskazówkę!

Ismael Miguel
źródło
Używanie 5**9zamiast 1<<20zapisywania jednego bajtu tutaj: PHP używa &do testowania flag IPv4 / IPv6 , więc dowolna liczba między 1048576 a 2097151 jest poprawna.
Benoit Esnard
W nowszych wersjach PHP ip2longnie zezwala na niekompletne adresy.
nwellnhof
@BenoitEsnard Dziękujemy! Dodałem go do odpowiedzi
Ismael Miguel
@nwellnhof Po przetestowaniu potwierdzam, że tak jest. Jednak nie sądzę, że warto go używać, ponieważ nie jest to wyraźnie udokumentowane.
Ismael Miguel
+!!nie jest wymagany; PO akceptuje teraz arbitralne prawdziwe wartości.
Tytus
5

Python 3: 81 78 70 69 66 bajtów

['%d.%d.%d.%d'%(*x.to_bytes(4,'big'),)for x in range(16**8)].count

Zapętlaj wszystkie możliwe adresy IPv4, uzyskaj reprezentację ciągu i porównaj go z danymi wejściowymi. Uruchomienie zajmuje trochę czasu.

EDYCJA: Usunięto 3 bajty, przechodząc z pełnego programu do funkcji anonimowej.

EDYCJA 2: Usunięto 8 bajtów przy pomocy xnor

EDYCJA 3: Usunięto 1 bajt za pomocą rozpakowanej mapy zamiast zrozumienia listy

EDYCJA 4: Usunięto 3 bajty za pomocą funkcji porównywania list zamiast ipaddressmodułu

mypetlion
źródło
2
Myślę, że twoja anonimowa funkcja może być po prostu [str(ip_address(x))for x in range(256**4)].count. Ponadto, 256**4może być 16**8.
xnor
5

C # (interaktywny kompilator Visual C #) , 84 79 65 bajtów

s=>s.Split('.').Sum(t=>byte.TryParse(t,out var b)&t==b+""?1:5)==4

Wypróbuj online!

-5 i -14 bajtów zapisanych dzięki @dana!

# C # (interaktywny kompilator Visual C #) , 61 bajtów

s=>s.Count(c=>c==46)==3&IPAddress.TryParse(s,out IPAddress i)

Wypróbuj online!

To jest praca w toku. Użyj kodu System.Net(+17 bajtów, jeśli go policzysz). jeśli zastanawiasz się, dlaczego liczę i analizuję:

Ograniczeniem metody IPAddress.TryParse jest to, że weryfikuje, czy ciąg może zostać przekonwertowany na adres IP, dlatego jeśli jest dostarczany z wartością ciągu, np. „5”, uznaje go za „0.0.0.5”.

źródło

Jak powiedział @milk w komentarzu, to rzeczywiście zawiedzie na zerach wiodących. Tak więc 61 bajtów nie działa.

aloisdg mówi Przywróć Monikę
źródło
1
@dana świetnie. Ładnie wykonane! Jeszcze cztery, a pobije 61 bajtów rozwiązań!
aloisdg mówi Przywróć Monikę
4

Python 2 , 85 82 81 bajtów

-1 bajt dzięki Kevin Cruijssen

from ipaddress import*
I=input()
try:r=I==str(IPv4Address(I))
except:r=0
print~~r

Wypróbuj online!

113 bajtowa odpowiedź jest usuwana, ponieważ nie działa1.1.1.1e-80

Dead Possum
źródło
1
Możesz grać print 1*rw golfa print~~r. +1, ponieważ wydaje się, że działa dla wszystkich sugerowanych dotychczas możliwych przypadków testowych . PS: Odpowiedź na 113 bajtów kończy się niepowodzeniem 1.1.1.1e-80.
Kevin Cruijssen
@KevinCruijssen Thanks! Nie myślałem o takim zapisie liczb
Dead Possum
Czy to nie ipaddressmoduł Python 3?
Farhan.K
@ Farhan.K Dunno, ale działa w TIO
Dead Possum
4

Japt, 17 15 bajtów

q.
ʶ4«Uk#ÿòs)Ê

Wypróbuj lub uruchom wszystkie przypadki testowe lub sprawdź dodatkowe przypadki testowe na podstawie komentarzy wyzwania


Wyjaśnienie

Dzielimy się na tablicę ., sprawdzamy, czy długość tej tablicy jest równa 4ORAZ i czy po ["0","255"]usunięciu z niej wszystkich elementów z zakresu jest falsey ( 0).

                 :Implicit input of string U
q.               :Split on "."
\n               :Reassign resulting array to U
Ê                :Length of U
 ¶4              :Equals 4?
   «             :&&!
    Uk           :Remove from U
      #ÿ         :  255
        ò        :  Range [0,255]
         s       :  Convert each to a string
          )      :End removal
           Ê     :Length of resulting array
Kudłaty
źródło
Niezła odpowiedź. Sprawdzono również wszystkie dotychczas sugerowane przypadki testowe . Ciekawe, jak to wyjaśnienie.
Kevin Cruijssen
2
@KevinCruijssen, dodano wyjaśnienie. Dzięki za te dodatkowe przypadki testowe.
Kudłaty
3

Mathematica, 39 31 bajtów

Orginalna wersja:

¬FailureQ[Interpreter["IPAddress"][#]]&

Wersja zmodyfikowana (dzięki Misha Lavrov)

 AtomQ@*Interpreter["IPAddress"]

który zwraca, Truejeśli wejście jest prawidłowym adresem IP ( spróbuj ).

W przypadku nalegania na uzyskanie 1i 0zamiast tego konieczne byłoby dodatkowe 7 bajtów:

Boole/@AtomQ@*Interpreter["IPAddress"]
polfosol ఠ_ఠ
źródło
Ponieważ Interpreter["IPAddress"]zwraca ciąg znaków dla poprawnych danych wejściowych, a niektóre skomplikowane obiekty błędów dla nieprawidłowych danych wejściowych, możemy przetestować poprawne dane wejściowe za pomocą AtomQ[Interpreter["IPAddress"][#]]&, które można dodatkowo skrócić do składu funkcji AtomQ@*Interpreter["IPAddress"]. Wypróbuj online!
Misza Ławrow
Nie działa na adresie IPv6, takim jak 2001:0db8:85a3:0000:0000:8a2e:0370:7334.
lirtosiast
3

JavaScript (ES6), 49 bajtów

Zwraca wartość logiczną.

s=>[0,1,2,3].map(i=>s.split`.`[i]&255).join`.`==s

Wypróbuj online!

Arnauld
źródło
3

Python 2, 93 89 67 53 bajtów

[i==`int(i)&255`for i in input().split('.')]!=[1]*4>_

Wypróbuj online!

Dzięki Dennisowi za golenie kolejnych 14 bajtów na wewnętrznych porównaniach i kodzie wyjścia.

Specjalne podziękowania dla Jonathana Allana za golenie 22 bajtów i poprawkę logiki! Pesky spróbuj / z wyjątkiem Begone!

Biorąc odpowiednio sformatowane ciągi zamiast surowych bajtów, golisz 4 bajty, dzięki Jo King.

TemporalWolf
źródło
Twój czek można zagrać w golfa i==`int(i)&255` . Możesz także wymusić błąd [...]!=[1]*4>_, ponieważ i tak używasz kodów wyjścia. Wypróbuj online!
Dennis
@Dennis Nie rozumiem, co >_robi. Bitowe i dość pomysłowe ... Nie udało mi się jednak ich połączyć.
TemporalWolf
2
Jeśli !=zwraca False, Python powoduje zwarcie i nic się nie dzieje; tłumacz ustnie. Jeśli zwraca wartość True, >_wywołuje błąd NameError, ponieważ zmienna _jest niezdefiniowana.
Dennis
Liczby Łączę porównania w mojej odpowiedzi, a następnie brakuje oczywistego wyniku w twoim komentarzu. Dziękuję za wyjaśnienie.
TemporalWolf
3

sfk , 176 bajtów

* pierwotnie był Bash + SFK, ale od tego czasu TIO dodało odpowiednie opakowanie SFK

xex -i "_[lstart][1.3 digits].[1.3 digits].[1.3 digits].[1.3 digits][lend]_[part2]\n[part4]\n[part6]\n[part8]_" +xed _[lstart]0[digit]_999_ +hex +linelen +filt -+1 -+2 +linelen

Wypróbuj online!

Obrzydliwe
źródło
Czy najpierw sprawdziłby wydruk błędu, aby go nc [addr] 1 -w1skrócić?
@Rogem ncakceptuje wiodące zera, a także adresy IPv6, więc nadal musiałbym sobie z nimi poradzić - i to i tak jest przeznaczone raczej jako sfkodpowiedź niż odpowiedź powłoki.
Οurous
3

Python3 Bash * 60

* Również inne muszle. Każdy, dla którego test prawdziwości / fałszowania przechodzi na kod wyjścia programu

read I
python3 -c "from ipaddress import*;IPv4Address('$I')"

Wyjaśnienie

Problem z czystymi rozwiązaniami Pythona polega na tym, że awaria programu jest uważana za nieokreśloną. Przydałoby się „dużo” kodu, aby przekonwertować wyjątek na odpowiednią wartość prawdy / fascy. Jednak w pewnym momencie interpreter języka Python obsługuje ten nieprzechwycony wyjątek i zwraca niezerowy kod wyjścia. Za niski i niski koszt zmiany języków na ulubioną powłokę uniksową możemy zaoszczędzić sporo kodu!

Oczywiście jest to podatne na ataki iniekcyjne ... Dane wejściowe, takie jak 1.1.1.1'); print('Doing Something Evilnielimitowane zagrożenie!

Sompom
źródło
( Wyjaśnienie to jest (nie wyjaśnieniu ).)
Peter Mortensen
@PeterMortensen Yikes. Zostało nawet podkreślone na czerwono. Moja przeglądarka próbowała mnie uratować, ale nie chciałem słuchać. Dzięki za złapanie tego!
Sompom,
Pełne programy mogą wyświetlać dane wyjściowe za pomocą kodów wyjścia, dlatego może to być 43 bajty .
ბიმო
@BMO Interesujące. Dzięki za zwrócenie na to uwagi! Myślę, że definiiton problemem zmieniona z „Truthy / Falsy” również pozwalając dowolnego wyjścia ponieważ napisałem, ale nie mogłem po prostu zauważyłem wcześniej :)
Sompom
3

ECMAScript czysty regex, 41 bajtów

^((2(?!5?[6-9])|1|(?!0\B))\d\d?\.?\b){4}$

Wypróbuj online!
Wypróbuj na regex101

Myślę, że logika tego wyrażenia regularnego mówi sama za siebie, więc po prostu wydrukuję dość ładnie, ale nie skomentuję tego:

^
(
    (
        2(?!5?[6-9])
    |
        1
    |
        (?!0\B)
    )
    \d\d?
    \.?\b
){4}
$

Można to wykorzystać do ogolenia 2 bajtów z następujących innych odpowiedzi:

Oto alternatywna wersja, która pozwala na zera na początku, ale robi to konsekwentnie (oktety mogą być reprezentowane przez maksymalnie 3 cyfry dziesiętne):

^((2(?!5?[6-9])|1|0?)\d\d?\.?\b){4}$

Lub zezwól na dowolną liczbę zer wiodących:

^(0*(2(?!5?[6-9])|1?)\d\d?\.?\b){4}$

Deadcode
źródło
1
\bi \B... jest mądry!
mazzy
1
@mazzy Tak, ci dwaj naprawdę się przydają! Mógłbym użyć (?!0\d)zamiast tego, ale lubię \Blepiej!
Deadcode
Odpowiedź programu PowerShell nie jest krótsza w przypadku wyrażenia regularnego. Przepraszam. Aby przekonwertować tablicę na ciąg, potrzebne są cudzysłowy. Wypróbuj online!
mazzy
1
\.?\bZaoszczędziło mi bajt na moją odpowiedź też, dzięki!
Neil
1
Zapisano 3 bajty dzięki
l4m2
2

Czerwony , 106 bajtów

func[s][if error? try[t: load s][return off]if 4 <> length? t[return off]s =
form as-ipv4 t/1 t/2 t/3 t/4]

Wypróbuj online!

Powrotny truelubfalse

Wyjaśnienie:

f: func [ s ] [
    if error? try [                  ; checks if the execution of the next block result in an error
        t: load s                    ; loading a string separated by '.' gives a tuple   
    ] [                              ; each part of which must be in the range 0..255
        return off                   ; if there's an error, return 'false' 
    ]
    if 4 <> length? t [              ; if the tuple doesn't have exactly 4 parts
        return off                   ; return 'false'  
    ]
    s = form as-ipv4 t/1 t/2 t/3 t/4 ; is the input equal to its parts converted to an IP adress
]
Galen Iwanow
źródło
2

Stax , 14 bajtów

∞n·Θ3ª&JH‼∙*~Γ

Uruchom i debuguj

Rozpakowane, niepolowane i skomentowane, wygląda to tak.

VB      constant 256
r       [0 .. 255]
'|*     coerce and string-join with "|"; i.e. "0|1|2|3 ... 254|255"
:{      parenthesize to "(0|1|2|3 ... 254|255)"
]4*     make 4-length array of number pattern
.\.*    string join with "\\."; this forms the complete regex
|Q      is the input a complete match for the regex?

Uruchom ten

rekurencyjny
źródło
Zaskoczony faktem, że stworzyłeś język Stax! działa dobrze.
rv7
Dzięki! Przestrzeń języków golfowych jest zaskakująco zatłoczona i nie jestem pewien, czy stax może uzasadnić swoje istnienie, ale moim głównym celem było sprawdzenie, czy mogę to zrobić i może się czegoś nauczyć. Skończyło się to zabawą, niż się spodziewano.
rekurencyjny
2

Python 3, 109 93 bajty

import re
lambda x:bool(re.match(r'^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(\.(?!$)|$)){4}$',x))

Wyjaśnienie

Każdy oktet może mieć wartość 0–255:

  • zaczyna się od 25 i ma 0-5 jako ostatnią cyfrę
  • zaczyna się od 2, ma 0-4 jako drugą cyfrę i dowolną cyfrę na końcu
  • zaczyna się od 1, a 00 - 99 jako cyfry spoczynkowe
  • ma tylko 2 cyfry - 1-9 jest pierwszą, a następnie dowolną cyfrą
  • lub tylko jedna cyfra

Oktet może kończyć się znakiem (.) Lub po prostu, pod warunkiem, że nie będzie w stanie wykonać obu tych czynności, negatywny lookahead (?!$)zajmuje się tym przypadkiem

Dzięki @Zachary za uświadomienie mi, że mogę odrzucić spacje (ponieważ jest to kod golfowy).
Dzięki @DLosc za ulepszenia i uświadomienie sobie mojego błędu, który został teraz poprawiony.

alpheus
źródło
2
Pomocne może być wyjaśnienie tego.
Nissa,
x: re.match=> x:re.match; , x=> ,xi ) is=> )ispowinny zapisać 3 bajty. Ponadto w wyrażeniu regularnym możesz użyć \ddla każdego wystąpienia [0-9]i [1]=> 1. Wydaje się, że to świetny pierwszy post!
Zacharý
[1-9][0-9]|[0-9]może stać się [1-9]\d|\d(zgodnie z radą Zachariego), co może się stać [1-9]?\d. Zamiast testowania re.match(...)is not Nonemożesz to zrobić, bool(re.match(...))ponieważ obiekty dopasowania są zgodne z prawdą i Nonefalsey. :)
DLosc
Hmm W rzeczywistości nie udaje się to w przypadku testowym 1.2.3.4.5(a także 1.2.3.4., który nie znajduje się na oficjalnej liście przypadków testowych), ponieważ może pasować do kropki zamiast końca łańcucha po czwartej cyfrze.
DLosc
2

Bash , 30 bajtów

ipcalc -c `cat`;echo $(($?^1))

Wypróbuj online!

Logern
źródło
Ta echo $(($?))część nie jest potrzebna, ponieważ programy mogą wyświetlać swój wynik za pomocą kodu wyjścia.
ბიმო
2

Węgiel drzewny , 45 21 bajtów

I∧⁼№θ.³¬Φ⪪θ.¬№E²⁵⁶Iλι

Wypróbuj online! Link jest do pełnej wersji kodu. Edycja: Zapisano 24 bajty, przenosząc odpowiedź @ Shaggy's Japt. Wyjaśnienie:

    θ                   Input string
   №                    Count occurrences of
     .                  Literal `.`
  ⁼                     Equal to
      ³                 Literal 3
 ∧                      Logical And
       ¬                Logical Not
          θ             Input string
         ⪪              Split on
           .            Literal `.`
        Φ               Filter by
            ¬           Logical Not
               ²⁵⁶      Literal 256
              E         Map over implicit range
                   λ    Map value
                  I     Cast to string
             №          Count occurrences of
                    ι   Filter value
I                       Cast to string
                        Implicitly print
Neil
źródło
Nie działa w przypadku przypadków testowych z ujemnymi liczbami całkowitymi, takimi jak 123.-50.0.12lub 1.1.1.-80. Wszystko inne wydaje się działać dobrze. Więc <256czek powinien być in [0,255]zamiast.
Kevin Cruijssen
@KevinCruijssen Właściwie kod do odfiltrowywania nieprawidłowych znaków nie działał, ponieważ zapomniałem zmienić zmienną w wewnętrznej pętli. Powinien zostać teraz naprawiony.
Neil,
2

Siatkówka , 46 44 bajtów

^
.
^(\.(25[0-5]|(2[0-4]|1\d|[1-9])?\d)){4}$

Port odpowiedzi Javy @ OlivierGrégoire , więc pamiętaj, aby go zagłosować!
-2 bajty dzięki @Neil .

Wypróbuj online .

Wyjaśnienie:

^
.                           # Prepend a dot "." before the (implicit) input
^...$                       # Check if the entire string matches the following regex
                            # exactly, resulting in 1/0 as truthy/falsey:
 (                          #  Open a capture group
  \.                        #   A dot "."
    (25[0-5]                #   Followed by a number in the range [250,255]
    |(2[0-4]|         ) \d) #   or by a number in the range [200,249]
    |(      |1\d|     ) \d) #   or by a number in the range [100,199]
    |(          |[1-9]) \d) #   or by a number in the range [10,99]
    |(                )?\d) #   or by a number in the range [0,9]
 )                          #  Close capture group
  {4}                       #  This capture group should match 4 times after each other
Kevin Cruijssen
źródło
Moja próba (której nie opublikowałem, ponieważ pytanie zostało wówczas zawieszone) była tej samej długości, ale nie miała \doptymalizacji grupy, więc możesz zapisać dwa bajty, ponieważ nie potrzebujesz Mspecyfikacji Ostatni wiersz.
Neil,
Udało mi się sprowadzić Retinę do 42 bajtów, przenosząc odpowiedź Perla 6, ale ta odpowiedź działa również w wersji 0.8.2, czego mój port nie robi.
Neil,
2

Galaretka , 11 bajtów

⁹ḶṾ€ṗ4j€”.ċ

102564=4294967296

16256

W jaki sposób?

⁹ḶṾ€ṗ4j€”.ċ - Link: list of characters, S
⁹           - literal 256
 Ḷ          - lowered range = [0,1,2,...,254,255]
  Ṿ€        - unevaluate €ach = ['0','1',...,['2','5','4'],['2','5','5']]
    ṗ4      - 4th Cartesian power = ALL 256^4 lists of 4 of them
            -               (e.g.: ['0',['2','5','5'],'9',['1','0']])
        ”.  - literal '.' character
      j€    - join for €ach (e.g. ['0','.','2','5','5','.','9','.','1','0'] = "0.255.9.10")
          ċ - count occurrences of right (S) in left (that big list)
Jonathan Allan
źródło
Dlaczego wersja z 65 536 adresami IP zajmuje 1,8 sekundy? o_O
Dennis
2

Siatkówka , 42 41 bajtów

~(K`

255*
["^(("|'|]")\.?\b){4}$"L$`
$.`

Wypróbuj online! Na podstawie poprzedniej wersji odpowiedzi Perla na @ nwellnhof 6, ale zapisano 1 bajt dzięki kradzieży \.?\bsztuczki z odpowiedzi @ Deadcode. Wyjaśnienie:

K`

Wyczyść obszar roboczy.

255*

Wstaw 255 znaków.

["^(("|'|]")\.?\b){4}$"L$`
$.`

Wygeneruj zakres 0..255 oddzielony |s, poprzedzony znakiem ^((i przyrostkiem )\.?\b){4}$, tworząc w ten sposób wyrażenie regularne ^((0|1|...255)\.?\b){4}$.

~(

Oceń to na oryginalnym wejściu.

Neil
źródło
1

Pip , 25 16 bajtów

a~=X,256RL4J"\."

Pobiera kandydujący adres IP jako argument wiersza polecenia. Wypróbuj online! lub Zweryfikuj wszystkie przypadki testowe

Wyjaśnienie

Rozwiązanie Regex, zasadniczo port odpowiedzi na rekurencyjne rozwiązanie Stax .

                  a is 1st cmdline arg (implicit)
    ,256          Range(256), i.e. [0 1 2 ... 255]
   X              To regex: creates a regex that matches any item from that list
                  i.e. essentially `(0|1|2|...|255)`
        RL4       Create a list with 4 copies of that regex
           J"\."  Join on this string
 ~=               Regex full-match
a                 against the input
DLosc
źródło
1

JavaScript, 89 bajtów

(_,r=`(${[...Array(256).keys()].join`|`})`)=>RegExp(`^${(r+'\\.').repeat(3)+r}$`).test(_)

Wypróbuj online!

Twórz RegExpgrupy przechwytywania na podstawie indeksów tablicy, length 256dla której zakres 0-255połączony z, |a następnie .znak ucieczki ( ^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$) powtarzają się 3razy zamykając z połączoną tablicą, po której następuje $dopasowanie końca łańcucha, powrotu truelub falsewyniku przekazanego do RegExp.prototype.test().

guest271314
źródło