Indirizzo IP o no?


25

Lo strumento di scansione della rete è fastidiosamente complicato per l'input e si blocca immediatamente se gli dai un indirizzo IPv4 che contiene caratteri non corretti o non è formattato correttamente.

Un indirizzo IPv4 è un indirizzo numerico a 32 bit scritto come quattro numeri separati da punti. Ogni numero può essere compreso tra zero e 255 .

Dobbiamo scrivere uno strumento per pre-validare l'input per evitare quegli arresti anomali, e il nostro strumento specifico è esigente: un formato valido apparirà come a.b.c.ddove a, b, c e d:

  • Può essere un 0numero naturale o senza zeri iniziali .
  • Dovrebbe essere compreso tra 0 e 255 (incluso).
  • Dovrebbe non contenere simboli speciali come +, -, ,, e altri.
  • Dovrebbe essere decimale (base 10)

Input : una stringa

Output : valore Verità o Falsey (sono accettati anche valori arbitrari)

Casi di prova :

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)

Questo è , quindi vinceranno meno byte!

Nota per gli utenti : se desideri aggiungere altri casi di test, sei il benvenuto (suggerendo una modifica). Ma, per favore, assicurati che i casi di test non si ripetano! Grazie


10
Suggerisci testcases: 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
Suggerire di aggiungere casi di test "1.2.3.4.5" (per escludere IP troppo lunghi) e "999.0.0.0" (per escludere IP troppo grandi).
Triggernometria

5
Forse un po 'schizzinoso, ma probabilmente dovresti fare riferimento a "indirizzi IPv4" piuttosto che a "indirizzi IP" - o almeno, menzionare da qualche parte che intendi solo indirizzi IPv4 - altrimenti 1234: 5678 :: 1 dovrebbe essere un indirizzo IP valido (mentre dalla descrizione è chiaro che non è previsto :)
psmears,

3
@Criggie La premessa non è quella di controllare effettivamente tutte le reali regole IP4 (come quelle che hai menzionato), è assicurarsi che la stringa di input non si blocchi in qualche altra app (presumibilmente mal scritta) che consente l'input solo in una forma molto specifica . Inoltre, non cambieremo le regole di una sfida che ha già oltre 30 risposte.
BradC,

2
@Criggie Vale la pena notare che la RFC dichiara che "Gli indirizzi hanno una lunghezza fissa di quattro ottetti". Penso che i casi marginali a cui stai riferendo siano più specializzati di questa sfida.
Colpisci il

Risposte:


26

Codice macchina X86_64: 18 16 byte

Modifica: questa risposta non funziona del tutto, come

  1. Sto usando inet_ptondalle librerie C standard, il che significa che ho bisogno di extern. Tuttavia non ho incluso l'esterno nel mio conteggio byte.
  2. Ho usato la zona rossa come risultato per l'indirizzo reale, ma ho chiamato una funzione che avrebbe potuto usare anche la zona rossa. Fortunatamente non funziona sulla mia macchina, ma una strana build di libreria standard potrebbe usarla che potrebbe causare un comportamento indefinito.

E sì, il tutto è praticamente fatto da una funzione già scritta

Comunque, questo è quello che ho ottenuto: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Montaggio:

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

Spiegazione:

Dai un'occhiata inet_pton(3). Prende un indirizzo IP stringa e lo inserisce in un buffer con cui è possibile utilizzarlo struct sockaddr. Sono necessari 3 argomenti: la famiglia di indirizzi ( AF_INET(ipv4), 2 o AF_INET6(ipv6), 10), la stringa dell'indirizzo IP e un puntatore all'output. Restituisce 1 in caso di successo, 0 per un indirizzo non valido o -1 per quando la famiglia di indirizzi non è né AF_INETo AF_INET6(che non si verificherà mai perché gli sto passando una costante).

Quindi sposto semplicemente la stringa nel registro per il secondo argomento, imposto il primo registro su 2 e imposto il terzo registro sulla zona rossa (128 byte sotto il puntatore dello stack) poiché non mi interessa il risultato. Quindi posso semplicemente jmpfarlo inet_ptone lasciare che ritorni direttamente al chiamante!

Ho sviluppato questo rapido programma di test per testare i tuoi casi:

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

Assembla nasm -felf64 assembly.asm, compila con gcc -no-pie test.c assembly.oe otterrai:

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

Potrei renderlo molto più piccolo se il chiamante dovesse passare AF_INETo AF_INET6alla funzione


4
Adoro che tu l'abbia fatto in asm. E il fatto che lo hai spiegato a coloro che potrebbero non capirlo (così come il codice di prova) è ancora meglio. Il che non vuol dire che avrei potuto farlo in asma; sono passati troppi anni ma ricordo abbastanza per vedere esattamente cosa dice (e quindi) la tua spiegazione. Buon lavoro.
Pryftan,

4
e9 00 00 00 00è un jmp near $+5, non un jmp inet_pton. Se si fornisce il codice operativo, è necessario includere la inet_ptonparte inclusa , non lasciare un vuoto
l4m2

1
15 byte-TIO 32 bit x86
Logern

3
dovresti includere l'esterno nel titolo della risposta, poiché il programma lo richiede e non è disponibile su tutte le piattaforme.
qwr,

1
"mov rdi, 2" può essere "push 2 / pop rdi" per -2 byte. Si noti inoltre che lo smontaggio è errato o il codice è errato. È "mov edi" (non rdi) o manca un prefisso.
peter ferrie il

13

Java (JDK) , 63 byte

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

Provalo online!

Crediti


Hai dimenticato di rimuovere il punto e virgola finale. ;) E posso verificare che funzioni per tutti i casi di test, compresi quelli nei commenti. Vedrò se vedo alcune cose da golf.
Kevin Cruijssen,

3
Errore.1.2.3.4
l4m2,

È consentito l'uso booleano quando esplicitamente richiede 0/1?
l4m2

1
@ l4m2 La domanda originale era valida / non valida. Quindi presumo che qualsiasi valore di verità / falsità sia accettabile qui.
Kevin Cruijssen,

Output: 0 or 1e Java non ha auto bool-> int
l4m2

12

JavaScript (Node.js) , 43 byte

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

Provalo online!

JavaScript (Node.js) , 46 byte

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

Provalo online!

usato la parte di Arnauld

JavaScript (Node.js) , 54 53 51 byte

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

Provalo online!

-2B per 0+t<256, -1B da Patrick Stephansen, + 1B per evitare input1.1.1.1e-80

Soluzione RegExp 58 54 byte

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

Grazie a Deadcode per 3 byte


Ho aggiunto alcuni casi di test!
rv7,


1
@KevinCruijssen 0.0.0.0è qui vero. Proprio perché SQL injection è qui?
l4m2

Ah aspetta, ho frainteso la frase nella descrizione della sfida. 0.0.0.0è davvero vero. Quella volontà di golf la mia risposta come pure .. (? E che cosa si intende per SQL injection: S Il collegamento è a TIO con casi di test ALL.)
Kevin Cruijssen

1
@ l4m2 L'ho aggiunto poiché abbiamo bisogno di alcuni test che non sembrano nemmeno un indirizzo IP.
TSH

11

PHP , 39 36 byte

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

Provalo online!

275 ricorda la costante FILTER_VALIDATE_IP

5 ** 9 viene utilizzato al posto della costante FILTER_FLAG_IPV4. Questo è sufficiente, perché 5**9 & FILTER_FLAG_IPV4è vero, che è esattamente ciò che fa PHP in background, come ha sottolineato Benoit Esnard.

Qui, filter_varrestituisce il primo argomento, se è un indirizzo IPv4 valido, o falso in caso contrario. Con +!!, produciamo l'output richiesto dalla sfida.


3
Usando 5**9invece di 1048576salvare 3 byte qui: PHP utilizza &per testare i flag IPv4 / IPv6 , quindi qualsiasi numero compreso tra 1048576 e 2097151 è valido.
Benoit Esnard,

Con la presente decido di votare la tua risposta per essere (sostanzialmente) la mia risposta: codegolf.stackexchange.com/a/174470/14732 che è stata scritta il 22-10-2010 09: 17: 34UTC mentre la tua è stata scritta il 22-10-2010 09: 21: 55UTC. Anche se ripristino l'ottimizzazione a 1 byte fornita da @BenoitEsnard, la mia risposta è esattamente la tua in termini di funzionalità.
Ismael Miguel,

2
Devo scusarmi, non ho visto la tua risposta, anche se al momento in cui la stavo componendo, in PHP non vi era alcuna presentazione su questa domanda (come hai detto, la differenza di tempo è inferiore a cinque minuti).
oktupol,

Lo so e lo capisco. Ho notato il tuo solo ora. Posso ripristinare il mio e mantenere l'ottimizzazione. Ma non so se rende la risposta abbastanza diversa l'una dall'altra.
Ismael Miguel,

17
@IsmaelMiguel Non vorrei sottovalutare qualcuno per questo se è plausibile che il tuo non fosse lì quando hanno iniziato. Con una differenza di 5 minuti, non solo è plausibile, è quasi certamente il caso, il che è evidente anche senza che l'autore lo dica lui stesso.
Duncan X Simpson,

11

PHP, 36 byte

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

ip2longè una nota funzione integrata .



Questo sembra usare funzionalità non documentate presenti nelle versioni più recenti (presumo che provenga da PHP7 +). Tieni presente che, per PHP 4 e 5, questo accetta IP incompleti.
Ismael Miguel,



1
Questo darà successo se gli dai un numero intero, come 1, 2, ecc. Non pensare che dovrebbe. E anche se gli dai da mangiare come 100.100.100
nl-x

10

Perl 6 , 22 21 20 byte

-1 byte grazie a Phil H.

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

Provalo online!

Spiegazione

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

3
Amico, devo passare più tempo a capire le regex di Perl 6. Non avevo nemmeno il %modificatore. Mi chiedo se prova a controllare tutte le 256**4possibilità?
Jo King,

1
Invece di <{^256}>te puoi semplicemente convertire l'intervallo in un array @(^256)per -1 char TIO . Modificando il blocco di codice in un array diventa anche molto più veloce (0.4s invece di> 30).
Phil H,

@PhilH Cool, grazie. Ci ho provato $(^256)ma ora capisco perché non ha funzionato.
nwellnhof,

9

05AB1E , 26 24 23 22 23 byte

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

-1 byte grazie a @Emigna .
+1 byte per il bug test che 1.1.1.1E1restituisce erroneamente un risultato veritiero.

Provalo online o verifica tutti i casi di test .

Spiegazione:

'.¡              '# 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)

1
Dovresti essere in grado di utilizzare Āinvece di<d
Emigna il

@MagicOctopusUrn Ho paura che non riesce per 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, e 0.00.10.255. (PS: ho risolto il 1.1.1.1E1þ
problema

Abbastanza giusto, ho pensato che mi mancasse qualcosa.
Magic Octopus Urn,

@MagicOctopusUrn Il problema principale è 05AB1E che vede numeri con 0 iniziali uguali a quelli senza, anche come stringa. Quale è il motivo per cui io uso il DïþJsJQcontrollo in cui ïgettò a int rimuovere 0 non significativi, e þsolo foglie cifre rimuovendo le cose come E, -ecc :) Il è per caso di test 0.00.10.255, dal momento che 00010255e 0010255sarebbe uguale.
Kevin Cruijssen,

Sì, ho attraversato la stessa assurdità, ma l'inversione di tutti i numeri ha funzionato abbastanza bene, tranne per quei casi. Interessante quando funzionalità utili per alcuni problemi diventano quasi bug-like per altri.
Magic Octopus Urn,

6

PowerShell, 59 51 49 byte

-8 byte, grazie @AdmBorkBork

-2 byte, trueo falseconsentito dall'autore

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

Script di prova:

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

Produzione:

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

Spiegazione:

Lo script tenta di analizzare una stringa di argomenti, per costruire un oggetto .NET, IPAddress .

  • restituisce $truese objectcreato e la stringa dell'argomento è uguale a una rappresentazione di stringa dell'indirizzo object(indirizzo normalizzato di object.toString())
  • ritorno $falsealtrimenti

PowerShell, 59 56 54 byte, alternativa "non usare una libreria .NET"

-3 byte trueo falseconsentito dall'autore

-2 byte, grazie a @ Deadcode per il fantastico regexp.

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

Provalo online!

Grazie @ Olivier Grégoire per l'espressione regolare originale.


1
Non è necessario chiamare |% t*gperché PowerShell eseguirà automaticamente il cast del lato destro di -eqcome stringa, poiché il lato sinistro è una stringa. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork,

Puoi ritagliare 2 byte dalla versione "non usare una lib di .NET" usando il mio regex (adattato al trucco del periodo di inserimento, che ovviamente non può essere nella mia versione perché è un regex puro): tio.run/…
Deadcode

5

C (gcc) / POSIX, 26 byte

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

Provalo online!

Funziona come codice a 64 bit su TIO ma probabilmente lo richiede sizeof(int) == sizeof(char*)su altre piattaforme.


@TobySpeight Sì, se sei su x86, probabilmente dovresti provare in modalità 32-bit ( -m32).
nwellnhof,

L'ho fatto funzionare, passando scome char*(nessun accesso a un sistema ILP32 qui), e sì, mi stavo mescolando inet_aton().
Toby Speight,

5

PHP 7+, 37 35 32 byte

Questo utilizza la funzione integrata filter_varper confermare che si tratta di un indirizzo IPv4 .

Perché funzioni, è necessario passare la chiave isu una richiesta GET.

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

Non genererà nulla (per un falsyrisultato) o IP (per un truthyrisultato), a seconda del risultato.

Puoi provare questo su: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Questo utilizza direttamente i seguenti valori:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (che ha il bit richiesto come "1", per 1048576)

Grazie a Benoit Esnard per questo suggerimento che mi ha salvato 1 byte!

Grazie a Titus per avermi ricordato le modifiche alla sfida.


Ho esaminato l'utilizzo della funzione ip2long, ma funziona con indirizzi IP non completi.

Gli indirizzi IPv4 non completi sono considerati non validi in questa sfida.

Se fossero autorizzati, questo sarebbe il codice finale (solo per PHP 5.2.10):

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

Attualmente, non è esplicito nella documentazione che questo smetterà di funzionare (quando viene passato un IP incompleto) con le nuove versioni di PHP.

Dopo i test, ha confermato che era così.

Grazie a nwellnhof per l'informazione!


Utilizzando 5**9invece di 1<<20salvare un byte qui: PHP utilizza &per testare i flag IPv4 / IPv6 , quindi qualsiasi numero compreso tra 1048576 e 2097151 è valido.
Benoit Esnard,

Nelle versioni più recenti di PHP, ip2longnon consente indirizzi incompleti.
nwellnhof,

@BenoitEsnard Grazie! L'ho aggiunto alla risposta
Ismael Miguel,

@nwellnhof Dopo il test, confermo che è così. Tuttavia, non penso che sia una buona idea usarlo, poiché non è esplicitamente documentato.
Ismael Miguel,

+!!non è richiesto; l'OP ora accetta valori di verità arbitrari.
Tito,

5

Python 3: 81 78 70 69 66 byte

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

Scorri tutti i possibili indirizzi IPv4, ottieni la rappresentazione della stringa e confrontala con l'input. Ci vuole un po 'di tempo per correre.

EDIT: rimossi 3 byte passando dal programma completo alla funzione anonima.

EDIT2: rimossi 8 byte con l'aiuto di xnor

EDIT3: rimosso 1 byte utilizzando una mappa decompressa anziché la comprensione dell'elenco

EDIT4: rimossi 3 byte utilizzando la comprensione dell'elenco anziché il ipaddressmodulo


2
Penso che la tua funzione anonima possa essere [str(ip_address(x))for x in range(256**4)].count. Inoltre, 256**4può essere 16**8.
xnor

5

C # (compilatore interattivo Visual C #) , 84 79 65 byte

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

Provalo online!

-5 e -14 byte salvati grazie a @dana!

# C # (compilatore interattivo Visual C #) , 61 byte

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

Provalo online!

Si tratta di un lavoro in corso. Il codice usa System.Net(+17 byte se lo conti). se ti chiedi perché conto e analizzo:

La limitazione con il metodo IPAddress.TryParse è che verifica se una stringa può essere convertita in indirizzo IP, quindi se viene fornita con un valore di stringa come "5", la considera come "0.0.0.5".

fonte

Come ha detto @milk nel commento, in effetti fallirà sugli zero iniziali. Quindi, i 61 byte uno non funziona.


1
@dana alla grande. Ben fatto! Altri quattro e supererà le soluzioni a 61 byte!
aloisdg dice Reinstate Monica il

4

Python 2 , 85 82 81 byte

-1 byte grazie a Kevin Cruijssen

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

Provalo online!

La risposta a 113 byte viene eliminata perché non riesce1.1.1.1e-80


1
Puoi giocare print 1*ra golf print~~r. +1 però, poiché sembra funzionare per tutti i possibili casi di test suggeriti finora . PS: la risposta di 113 byte non riesce per 1.1.1.1e-80.
Kevin Cruijssen,

@KevinCruijssen Grazie! Non pensavo a una tale notazione di numeri
Dead Possum,

Non è ipaddressun modulo Python 3?
Farhan.K,

@ Farhan.K Non so, ma funziona in TIO
Dead Possum

4

Japt, 17 15 byte

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

Provalo o esegui tutti i casi di test o verifica altri casi di test dai commenti della sfida


Spiegazione

Ci dividiamo in un array acceso ., controlliamo che la lunghezza di quell'array sia uguale a 4AND che la lunghezza quando tutti gli elementi dell'intervallo ["0","255"]vengono rimossi da esso è false ( 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

Bella risposta. Finora verificato anche per tutti i casi di test suggeriti . Curioso di vedere quella spiegazione.
Kevin Cruijssen,

2
@KevinCruijssen, spiegazione aggiunta. Grazie per quei casi di test aggiuntivi.
Shaggy,

3

Mathematica, 39 31 byte

Versione originale:

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

Versione modificata (grazie a Misha Lavrov)

 AtomQ@*Interpreter["IPAddress"]

che restituisce Truese l'input è un indirizzo IP valido ( provalo ).

Nel caso in cui insisti per ottenere 1e 0invece, sarebbero necessari ulteriori 7 byte:

Boole/@AtomQ@*Interpreter["IPAddress"]

Poiché Interpreter["IPAddress"]restituisce una stringa per input validi e alcuni complicati oggetti di errore per input non validi, possiamo testare input validi con AtomQ[Interpreter["IPAddress"][#]]&, che possono essere ulteriormente abbreviati nella composizione della funzione AtomQ@*Interpreter["IPAddress"]. Provalo online!
Misha Lavrov,

Non riesce su un indirizzo IPv6 come 2001:0db8:85a3:0000:0000:8a2e:0370:7334.
Lirtosiast

3

JavaScript (ES6), 49 byte

Restituisce un valore booleano.

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

Provalo online!


3

Python 2, 93 89 67 53 byte

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

Provalo online!

Grazie a Dennis per aver rasato altri 14 byte sui confronti interni e sul codice di uscita.

Un ringraziamento speciale a Jonathan Allan per la rasatura di 22 byte e una correzione logica! Prova fastidiosa / tranne begone!

Prendendo stringhe correttamente formattate anziché byte non elaborati, si rade 4 byte, grazie Jo King.


Il tuo assegno può essere giocato a golf i==`int(i)&255` . Inoltre, puoi forzare un errore con [...]!=[1]*4>_, poiché stai usando comunque i codici di uscita. Provalo online!
Dennis,

@Dennis Non capisco cosa >_. Il bit per bit ed è abbastanza ingegnoso però ... Non sono riuscito a combinare quelli me stesso.
TemporalWolf,

2
Se !=restituisce False, Python mette in corto circuito e non succede nulla; l'interprete esce normalmente. Se restituisce True, >_genera un NameError, poiché la variabile _non è definita.
Dennis,

Figure I concatenano i confronti nella mia risposta e quindi mi manca il risultato evidente nel tuo commento. Grazie per la spiegazione.
TemporalWolf,

3

sfk , 176 byte

* era originariamente Bash + SFK ma da allora TIO ha aggiunto un wrapper SFK appropriato

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

Provalo online!


Controllare innanzitutto la stampa dell'errore per nc [addr] 1 -w1accorciarlo?

@Rogem ncaccetta gli zero iniziali e gli indirizzi IPv6, quindi dovrei comunque gestirli - e questo è inteso più come una sfkrisposta che come una risposta della shell.
Οurous

3

Python3 Bash * 60

* Anche altre conchiglie. Qualcuno per cui il test di verità / falsità passa un codice di uscita del programma

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

Spiegazione

Il problema con soluzioni Python pure è che un crash del programma è considerato indeterminato. Potremmo usare un "sacco" di codice per convertire un'eccezione in un valore di verità / verità corretto. Tuttavia, a un certo punto l'interprete Python gestisce questa eccezione non rilevata e restituisce un codice di uscita diverso da zero. Per il basso costo del cambio delle lingue nella tua shell Unix preferita, possiamo risparmiare un bel po 'di codice!

Certo, questo è vulnerabile agli attacchi di iniezione ... Gli input come 1.1.1.1'); print('Doing Something Eviluna minaccia non criticata!


( Spiegazione è (non spiegazione ).)
Peter Mortensen,

@PeterMortensen Yikes. È stato anche sottolineato in rosso. Il mio browser ha tentato di salvarmi, ma non avrei ascoltato. Grazie per averlo colto!
Sompom,

L' output dei programmi completi è consentito tramite codici di uscita, pertanto potrebbero essere 43 byte .
ბიმო

@BMO Interessante. Grazie per la segnalazione! Penso che la definizione del problema sia cambiata da "Truthy / Falsy" a consentire anche l'output arbitrario da quando l'ho pubblicato, ma non avrei potuto
notarlo

3

ECMAScript regex puro, 41 byte

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

Provalo online!
Provalo su regex101

Penso che la logica in questa regex parli da sola, quindi mi limiterò a stampare piuttosto ma non commentarla:

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

Questo può essere usato per eliminare 2 byte dalle seguenti altre risposte:

Ecco una versione alternativa che consente zeri iniziali, ma lo fa in modo coerente (gli ottetti possono essere rappresentati da un massimo di 3 cifre decimali):

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

O consenti un numero qualsiasi di zeri iniziali:

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


1
\be \B... è intelligente!
mazzy

1
@mazzy Sì, quei due sono davvero utili! Avrei potuto usare (?!0\d)invece, ma mi piace di \Bpiù!
Deadcode

La risposta PowerShell non si accorcia con regexp. Mi dispiace. Le virgolette sono necessarie per convertire un array in una stringa. Provalo online!
mazzy

1
Il \.?\bmi ha salvato un byte sulla mia risposta anche, grazie!
Neil,

1
Salvato 3 byte grazie
l4m2

2

Rosso , 106 byte

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]

Provalo online!

Returnd trueofalse

Spiegazione:

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
]

2

Stax , 14 byte

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

Esegui ed esegui il debug

Disimballato, non golfato e commentato, sembra così.

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?

Esegui questo


Sorpreso di sapere che hai creato la lingua Stax! sta funzionando bene.
rv7,

Grazie! Lo spazio delle lingue del golf è sorprendentemente affollato, e non sono sicuro che lo stax possa giustificare la sua esistenza per i suoi meriti, ma il mio obiettivo principale era solo quello di vedere se potevo farlo e forse imparare qualcosa. Alla fine è stato più divertente del previsto.
ricorsivo il

2

Python 3, 109 93 byte

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

Spiegazione

Ogni ottetto può essere compreso tra 0 e 255:

  • inizia con 25 e con 0-5 come ultima cifra
  • inizia con 2, ha 0-4 come seconda cifra e qualsiasi cifra alla fine
  • inizia con 1 e 00 - 99 come cifre di riposo
  • ha solo 2 cifre - 1-9 è la prima e qualsiasi cifra successiva
  • o solo una singola cifra

Un ottetto può terminare con un (.) O semplicemente terminare, a condizione che non sia in grado di fare entrambe le cose, lo sguardo negativo (?!$)si occupa di questo caso

Grazie @Zachary per avermi fatto capire che posso scartare gli spazi (dato che si tratta di codice golf)
Grazie @DLosc per i miglioramenti e per avermi fatto capire il mio errore, ora è stato corretto.


2
Qualche spiegazione per questo potrebbe aiutare.
Nissa,

x: re.match=> x:re.match; , x=> ,xe ) is=> )isdovrebbero salvare 3 byte. Inoltre, nella regex, è possibile utilizzare \dper ogni occorrenza di [0-9]e [1]=> 1. Questo sembra un ottimo primo post, però!
Zacharý,

[1-9][0-9]|[0-9]può diventare [1-9]\d|\d(su consiglio di Zacharý), che può diventare [1-9]?\d. Inoltre, invece di testare re.match(...)is not None, puoi farlo bool(re.match(...))poiché gli oggetti match sono veritieri e Nonefalsi. :)
DLosc,

Hmm. In realtà, ciò fallisce nel caso di test 1.2.3.4.5(e anche 1.2.3.4., che non è nell'elenco ufficiale dei casi di test), perché può corrispondere a un punto anziché alla fine della stringa dopo il quarto numero.
DLosc,


2

Carbone , 45 21 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Modifica: salvato 24 byte eseguendo il porting della risposta Japt di Shaggy. Spiegazione:

    θ                   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

Errore nei casi di test con numeri interi negativi come 123.-50.0.12o 1.1.1.-80. Tutto il resto sembra funzionare bene. Quindi il <256controllo dovrebbe essere in [0,255]invece.
Kevin Cruijssen,

@KevinCruijssen In realtà il codice per filtrare i caratteri non validi non funzionava perché avevo dimenticato di cambiare la variabile nel ciclo interno. Ora dovrebbe essere risolto.
Neil,

2

Retina , 46 44 byte

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

La risposta Java di Port of @ OlivierGrégoire , quindi assicurati di votarlo!
-2 byte grazie a @Neil .

Provalo online .

Spiegazione:

^
.                           # 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

Il mio tentativo (che non ho pubblicato perché la domanda è stata messa in attesa in quel momento) era della stessa lunghezza, ma non aveva l' \dottimizzazione del gruppo, quindi puoi salvare due byte perché non hai bisogno delle Mspecifiche sul ultima linea.
Neil,

Sono riuscito a portare Retina a 42 byte eseguendo il porting della risposta Perl 6, ma questa risposta funziona anche in 0.8.2, ma la mia porta no.
Neil,

2

Gelatina , 11 byte

⁹ḶṾ€ṗ4j€”.ċ

102564=4294967296

16256

Come?

⁹ḶṾ€ṗ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)

Perché la versione con 65.536 IP impiega 1,8 secondi? o_O
Dennis,

2

Retina , 42 41 byte

~(K`

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

Provalo online! Basato su una versione precedente della risposta Perl 6 di @ nwellnhof, ma 1 byte salvato rubando il \.?\btrucco dalla risposta di @ Deadcode. Spiegazione:

K`

Cancella l'area di lavoro.

255*

Inserisci 255 caratteri.

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

Genera l'intervallo 0..255 separato da |s, con prefisso ^((e suffisso )\.?\b){4}$, creando così l'espressione regolare ^((0|1|...255)\.?\b){4}$.

~(

Valutalo sull'input originale.


1

Pip , 25 16 byte

a~=X,256RL4J"\."

Prende l'indirizzo IP candidato come argomento della riga di comando. Provalo online! oppure Verifica tutti i casi di test

Spiegazione

Soluzione Regex, essenzialmente una porta di risposta Stax ricorsiva .

                  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

1

JavaScript, 89 byte

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

Provalo online!

Creare RegExpgruppi di acquisizione da indici di un array con length 256intervallo 0-255unito a |e seguito da .caratteri di escape ( ^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$) ripetuti 3volte chiudendo con array unito seguito da $per far corrispondere la fine della stringa, il ritorno trueo il falserisultato dell'input passato a RegExp.prototype.test().

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.