Dirección IP o no?


25

Su herramienta de escaneo de red es irritantemente exigente con la entrada, e inmediatamente se bloquea si la alimenta con una dirección IPv4 que contiene caracteres incorrectos o no está formateada correctamente.

Una dirección IPv4 es una dirección numérica de 32 bits escrita como cuatro números separados por puntos. Cada número puede ser de cero a 255 .

Necesitamos escribir una herramienta para validar previamente la entrada para evitar esos bloqueos, y nuestra herramienta específica es exigente: se verá un formato válidoa.b.c.d donde a, b, c y d:

  • Puede ser un 0número natural o sin ceros a la izquierda .
  • Debe estar entre 0 y 255 (inclusive).
  • En caso de no incluir los símbolos especiales como +, -, ,, y otros.
  • Debe ser decimal (base 10)

Entrada : una cadena

Salida : valor de Verdad o Falsey (también se aceptan valores arbitrarios)

Casos de prueba :

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)

Este es el , ¡por lo que ganarán menos bytes!

Nota para los usuarios : si desea agregar más casos de prueba, será bienvenido (sugiriendo una edición). Pero, ¡asegúrese de que los casos de prueba no se repitan! Gracias


10
Sugieren casos de prueba: 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

55
Sugiera agregar casos de prueba "1.2.3.4.5" (para descartar direcciones IP demasiado largas) y "999.0.0.0" (para descartar direcciones IP demasiado grandes).
Triggernometry

55
Posiblemente un poco exigente, pero probablemente debería referirse a "direcciones IPv4" en lugar de "direcciones IP", o al menos, mencionar en alguna parte que solo se refiere a direcciones IPv4; de lo contrario, 1234: 5678 :: 1 debería ser una dirección IP válida (mientras que de la descripción está claro que eso no está destinado :)
psmears

3
@Criggie La premisa no es verificar todas las reglas IP4 reales (como las que mencionó), es asegurarse de que la cadena de entrada no bloquee alguna otra aplicación (presumiblemente mal escrita) que solo permite la entrada en una forma muy específica . Además, no vamos a cambiar las reglas de un desafío que ya tiene más de 30 respuestas.
BradC

2
@Criggie Vale la pena señalar que el RFC declara que "las direcciones tienen una longitud fija de cuatro octetos". Creo que los casos marginales a los que hace referencia son más especializados que este desafío.
Poke

Respuestas:


26

Código máquina X86_64: 18 años 16 bytes

Editar: esta respuesta no funciona, ya que

  1. Estoy usando inet_ptonde las bibliotecas C estándar, lo que significa que necesito el externo. Sin embargo, no incluí el externo en mi recuento de bytes.
  2. Utilicé la zona roja como resultado de la dirección real, pero llamé a una función que también podría haber utilizado la zona roja. Afortunadamente no funciona en mi máquina, pero algunas compilaciones de biblioteca estándar extrañas podrían usarlo, lo que podría causar un comportamiento indefinido.

Y sí, todo se está haciendo prácticamente por una función ya escrita

De todos modos, esto es lo que obtuve: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Montaje:

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

Explicación:

Echa un vistazo a inet_pton(3). Toma una dirección IP de cadena y la coloca en un búfer con el que puede usar struct sockaddr. Toma 3 argumentos: la familia de direcciones ( AF_INET(ipv4), 2 o AF_INET6(ipv6), 10), la cadena de la dirección ip y un puntero a la salida. Devuelve 1 en caso de éxito, 0 para una dirección no válida o -1 para cuando la familia de direcciones es ninguno AF_INETo AF_INET6(lo que nunca ocurrirá porque le estoy pasando una constante).

Entonces, simplemente muevo la cadena al registro para el segundo argumento, establezco el primer registro en 2 y establezco el tercer registro en la zona roja (128 bytes debajo del puntero de la pila) ya que no me importa el resultado. Entonces puede simplemente jmpa inet_ptony dejar que el regreso directamente a la persona que llama!

Hice girar este programa de prueba rápida para probar sus casos:

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

Ensambla nasm -felf64 assembly.asm, compila gcc -no-pie test.c assembly.oy obtendrás:

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

Podría hacer esto mucho más pequeño si se supone que la persona que llama debe pasar AF_INETo AF_INET6a la función


44
Me encanta que hiciste esto en asm. Y el hecho de que lo haya explicado a aquellos que podrían no entenderlo (así como el código de prueba) es aún mejor. Lo que no quiere decir que podría haberlo hecho en asm; Han pasado demasiados años, pero recuerdo lo suficiente como para ver exactamente lo que dice su explicación (y, por lo tanto, el proceso). Buen trabajo.
Pryftan

44
e9 00 00 00 00es un jmp near $+5, no un jmp inet_pton. Si proporciona código de operación, debe incluir la inet_ptonparte que incluye , no dejar un espacio en blanco
l4m2 el

1
15 bytes-TIO 32bit x86
Logern

3
debe incluir el externo en el título de la respuesta, ya que el programa lo requiere y no está disponible en todas las plataformas.
qwr

1
el "mov rdi, 2" puede ser "push 2 / pop rdi" para -2 bytes. Tenga en cuenta también que el desmontaje es incorrecto o que el código es incorrecto. Es "mov edi" (no rdi) o falta un prefijo.
Peter Ferrie

13

Java (JDK) , 63 bytes

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

Pruébalo en línea!

Créditos

  • -1 byte gracias a Kevin Cruijssen
  • l4m2 para mostrar el caso que fallaba anteriormente .1.1.1.1.

Olvidó eliminar el punto y coma final. ;) Y puedo verificar que funciona para todos los casos de prueba, incluidos los de los comentarios. Veré si veo algunas cosas al golf.
Kevin Cruijssen

3
Falló el.1.2.3.4
l4m2 el

¿Está permitido usar booleano cuando explícitamente requiere 0/1?
l4m2

1
@ l4m2 La pregunta original tenía Válido / Inválido. Así que supongo que cualquier valor verdadero / falso es aceptable aquí.
Kevin Cruijssen

Output: 0 or 1y Java no tiene bool automático-> int
l4m2

12

JavaScript (Node.js) , 43 bytes

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

Pruébalo en línea!

JavaScript (Node.js) , 46 bytes

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

Pruébalo en línea!

utiliza la parte de Arnauld

JavaScript (Node.js) , 54 53 51 bytes

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

Pruébalo en línea!

-2B para 0+t<256, -1B de Patrick Stephansen, + 1B para evitar la entrada1.1.1.1e-80

Solución RegExp 58 54 bytes

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

Gracias Deadcode por 3 bytes


¡He agregado algunos casos de prueba!
RV7


1
@KevinCruijssen 0.0.0.0es aquí una verdadera. ¿Por qué la inyección SQL está aquí?
l4m2

Ah, espera, interpreto mal la frase en la descripción del desafío. 0.0.0.0De hecho es verdad. Que el golf voluntad mi respuesta, así .. (? Y ¿qué es lo que entendemos por inyección de SQL: S El enlace es a TIO con casos de prueba de todo.)
Kevin Cruijssen

1
@ l4m2 Lo agregué porque necesitamos algunos casos de prueba que incluso no parecen una dirección IP.
tsh

11

PHP , 39 36 bytes

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

Pruébalo en línea!

275 se asemeja a la constante FILTER_VALIDATE_IP

Se está usando 5 ** 9 en lugar de la constante FILTER_FLAG_IPV4. Esto es suficiente, porque 5**9 & FILTER_FLAG_IPV4es verdad, que es exactamente lo que PHP hace en segundo plano, como señaló Benoit Esnard.

Aquí, filter_vardevuelve el primer argumento, si es una dirección IPv4 válida, o falso si no lo es. Con +!!, producimos la salida requerida por el desafío.


3
Usando en 5**9lugar de 1048576guardar 3 bytes aquí: PHP usa &para probar los indicadores IPv4 / IPv6 , por lo que cualquier número entre 1048576 y 2097151 es válido.
Benoit Esnard

Por la presente, rechazo su respuesta por ser (básicamente) mi respuesta: codegolf.stackexchange.com/a/174470/14732 que se escribió en 2018-10-22 09: 17: 34UTC mientras que la suya se escribió en 2018-10-22 09: 21: 55UTC. Incluso si revierto la optimización de 1 byte dada por @BenoitEsnard, mi respuesta es exactamente la misma que la suya en cuanto a funcionalidad.
Ismael Miguel

2
Tengo que disculparme, no vi su respuesta, aunque en el momento en que la estaba componiendo, no había ninguna presentación en PHP sobre esta pregunta (como usted dijo, la diferencia horaria es inferior a cinco minutos).
Oktupol

Lo sé y lo entiendo. Solo noté el tuyo justo ahora. Puedo hacer retroceder el mío, y tú mantienes la optimización. Pero no sé si hace que la respuesta sea lo suficientemente diferente entre sí.
Ismael Miguel

17
@IsmaelMiguel No despreciaría a nadie por eso si es plausible que el tuyo no estuviera allí cuando comenzaron. Con una diferencia de 5 minutos, no solo es plausible, es casi seguro el caso, lo que es evidente incluso sin que el autor lo diga.
Duncan X Simpson

11

PHP, 36 bytes

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

ip2longes una conocida función incorporada .



Esto parece usar características no documentadas presentes en versiones más recientes (supongo que es de PHP7 +). Tenga en cuenta que, para PHP 4 y 5, esto acepta direcciones IP incompletas.
Ismael Miguel



1
Esto le dará éxito si le da un número entero, como 1, 2, etc. No piense que debería. Y también si lo alimentas algo como 100.100.100
nl-x

10

Perl 6 , 22 21 20 bytes

-1 byte gracias a Phil H.

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

Pruébalo en línea!

Explicación

{                  }  # 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
Hombre, necesito pasar más tiempo descubriendo las expresiones regulares de Perl 6. Tampoco tenía el %modificador existía. Me pregunto si intenta comprobar todas las 256**4posibilidades.
Jo King el

1
En lugar de <{^256}>eso, solo puede convertir el rango en una matriz @(^256)para -1 char TIO . Al cambiar el bloque de código a una matriz, también se vuelve enormemente más rápido (0.4s en lugar de> 30).
Phil H

@PhilH Cool, gracias. Lo intenté $(^256)pero ahora me doy cuenta de por qué esto no funcionó.
nwellnhof

9

05AB1E , 26 24 23 22 23 bytes

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

-1 byte gracias a @Emigna .
+1 byte para el caso de prueba de corrección de errores que 1.1.1.1E1devuelve incorrectamente un resultado verdadero.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

'.¡              '# 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
Debería poder usar en Ālugar de<d
Emigna

@MagicOctopusUrn Me temo que no para 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, y 0.00.10.255. (PD: lo arreglé 1.1.1.1E1agregando el þal control de
combinación

Muy bien, supuse que me perdí algo.
Urna mágica de pulpo

@MagicOctopusUrn El problema principal es que 05AB1E ve números con 0 iniciales iguales a los que no tienen, incluso como cadena. Razón por la cual utilizo el DïþJsJQcheque donde ïechó a int para eliminar 0s principales, y þsólo las hojas dígitos quitando cosas como E, -, etc. :) El es para casos de prueba 0.00.10.255, puesto 00010255y 0010255sería igual.
Kevin Cruijssen

Sí, pasé por el mismo sinsentido, aunque la reversión de todos los números funcionó bastante bien, excepto en esos casos. Interesante cuando las características beneficiosas para algunos problemas se vuelven casi parecidas a errores para otros.
Urna de pulpo mágico el

6

PowerShell, 59 51 49 bytes

-8 bytes, gracias @AdmBorkBork

-2 bytes, trueo falsepermitido por el autor

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

Script de prueba:

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

Salida:

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

Explicación:

El script intenta analizar una cadena de argumento para construir un objeto .NET, IPAddress .

  • devolver $truesi se objectcreó y la cadena de argumento es igual a una representación de cadena de object(dirección normalizada por object.toString())
  • volver de lo $falsecontrario

PowerShell, 59 56 54 bytes, alternativa 'no use una lib .NET'

-3 bytes, trueo falsepermitido por el autor

-2 bytes, gracias a @ Deadcode por la genial expresión regular .

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

Pruébalo en línea!

Gracias @ Olivier Grégoire por la expresión regular original.


1
No debería necesitar llamar |% t*gya que PowerShell convertirá automáticamente el lado derecho de -eqcomo una cadena, porque el lado izquierdo es una cadena. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork

Puede tallar 2 bytes de la versión "no use una lib .NET" usando mi expresión regular (adaptada al truco de insertar un período, que por supuesto no puede estar en mi versión porque es una expresión regular pura): tio.run/…
Deadcode

5

C (gcc) / POSIX, 26 bytes

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

Pruébalo en línea!

Funciona como código de 64 bits en TIO, pero probablemente lo requiera sizeof(int) == sizeof(char*)en otras plataformas.


@TobySpeight Sí, si estás en x86, probablemente deberías probar en modo de 32 bits ( -m32).
nwellnhof

Lo puse a trabajar, pasando scomo un char*(sin acceso a un sistema ILP32 aquí), y sí, me estaba mezclando inet_aton().
Toby Speight

5

PHP 7+, 37 35 32 bytes

Esto utiliza la función incorporada filter_var, para validar que es una dirección IPv4 .

Para que funcione, debe pasar la clave isobre una solicitud GET.

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

No generará nada (para un falsyresultado) o la IP (para un truthyresultado), dependiendo del resultado.

Puedes probar esto en: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Esto usa los siguientes valores directamente:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (que tiene el bit requerido como "1", para 1048576)

¡Gracias a Benoit Esnard por este consejo que me salvó 1 byte!

Gracias a Titus por recordarme los cambios al desafío.


He ip2longinvestigado el uso de la función , pero funciona con direcciones IP no completas.

Las direcciones IPv4 no completas se consideran inválidas en este desafío.

Si se les permitiera, este sería el código final (solo para PHP 5.2.10):

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

Actualmente, no está explícito en la documentación que esto dejará de funcionar (cuando se pasa una IP incompleta) con las nuevas versiones de PHP.

Después de la prueba, confirmó que ese era el caso.

Gracias a nwellnhof por la informacion!


Usando en 5**9lugar de 1<<20guardar un byte aquí: PHP usa &para probar los indicadores IPv4 / IPv6 , por lo que cualquier número entre 1048576 y 2097151 es válido.
Benoit Esnard

En versiones PHP más recientes, ip2longno permite direcciones incompletas.
nwellnhof

@BenoitEsnard ¡Gracias! Lo he agregado a la respuesta
Ismael Miguel

@nwellnhof Después de las pruebas, confirmo que ese es el caso. Sin embargo, no creo que sea una buena idea usarlo, ya que no está documentado explícitamente.
Ismael Miguel

+!!no es requerido; el OP ahora acepta valores de verdad arbitrarios.
Tito el

5

Python 3: 81 78 70 69 66 bytes

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

Recorra todas las direcciones IPv4 posibles, obtenga la representación de cadena y compárela con la entrada. Es ... lleva un tiempo correr.

EDITAR: Se eliminaron 3 bytes al cambiar del programa completo a la función anónima.

EDIT2: eliminado 8 bytes con ayuda de xnor

EDITAR3: se eliminó 1 byte usando un mapa desempaquetado en lugar de la comprensión de la lista

EDIT4: se eliminaron 3 bytes mediante el uso de la comprensión de la lista en lugar del ipaddressmódulo


2
Creo que tu función anónima puede ser [str(ip_address(x))for x in range(256**4)].count. Además, 256**4puede ser 16**8.
xnor

5

C # (compilador interactivo de Visual C #) , 84 79 65 bytes

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

Pruébalo en línea!

-5 y -14 bytes guardados gracias a @dana!

# C # (compilador interactivo de Visual C #) , 61 bytes

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

Pruébalo en línea!

Este es un trabajo en progreso. El uso del código System.Net(+17 bytes si lo cuenta). si te preguntas por qué cuento y analizo:

La limitación con el método IPAddress. TryParse es que verifica si una cadena se puede convertir a una dirección IP, por lo tanto, si se le proporciona un valor de cadena como "5", lo considera como "0.0.0.5".

fuente

Como @milk dijo en un comentario, fallará en ceros a la izquierda. Entonces, el de 61 bytes no está funcionando.


1
@dana genial. ¡Bien hecho! ¡Cuatro más y superará las soluciones de 61 bytes!
aloisdg dice Reinstate Monica el

4

Python 2 , 85 82 81 bytes

-1 byte gracias a Kevin Cruijssen

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

Pruébalo en línea!

La respuesta de 113 bytes se elimina porque falla1.1.1.1e-80


1
Puedes jugar print 1*ral golf print~~r. Sin embargo, +1, ya que parece funcionar para todos los casos de prueba posibles sugeridos hasta ahora . PD: Su respuesta de 113 bytes falla 1.1.1.1e-80.
Kevin Cruijssen

@KevinCruijssen ¡Gracias! No pensé en tal notación de números
Dead Possum

¿No es ipaddressun módulo Python 3?
Farhan.K

@ Farhan.K Dunno, pero funciona en TIO
Dead Possum

4

Japt, 17 15 bytes

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

Pruébelo o ejecute todos los casos de prueba o verifique casos de prueba adicionales a partir de comentarios de desafío


Explicación

Nos dividimos en una matriz activada ., verificamos que la longitud de esa matriz sea igual a 4AND y que la longitud cuando ["0","255"]se eliminan todos los elementos del rango sea ​​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

Buena respuesta. También verificado para todos los casos de prueba sugeridos hasta ahora . Curioso por ver esa explicación.
Kevin Cruijssen

2
@KevinCruijssen, explicación agregada. Gracias por esos casos de prueba adicionales.
Shaggy

3

Mathematica, 39 31 bytes

Versión original:

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

Versión modificada (gracias a Misha Lavrov)

 AtomQ@*Interpreter["IPAddress"]

que vuelve Truesi la entrada es una dirección IP válida ( pruébelo ).

En caso de que insista en obtener 1y 0, en cambio, serían necesarios 7 bytes adicionales:

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

Dado que Interpreter["IPAddress"]devuelve una cadena para una entrada válida, y algún objeto de falla complicado para una entrada no válida, podemos probar entradas válidas con AtomQ[Interpreter["IPAddress"][#]]&, que se pueden acortar aún más a la composición de la función AtomQ@*Interpreter["IPAddress"]. Pruébalo en línea!
Misha Lavrov

Falla en una dirección IPv6 como 2001:0db8:85a3:0000:0000:8a2e:0370:7334.
lirtosiast el


3

Python 2, 93 89 67 53 bytes

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

Pruébalo en línea!

Gracias a Dennis por reducir otros 14 bytes en las comparaciones internas y el código de salida.

¡Un agradecimiento especial a Jonathan Allan por reducir 22 bytes y una solución lógica! Intento molesto / excepto desaparecido!

Tomar cadenas formateadas correctamente en lugar de bytes sin formato elimina 4 bytes, gracias Jo King.


Su cheque puede ser enviado a golf i==`int(i)&255` . Además, puede forzar un error [...]!=[1]*4>_, ya que de todos modos está utilizando códigos de salida. Pruébalo en línea!
Dennis

@ Dennis No entiendo lo que >_hace. Sin embargo, es bastante ingenioso ... No tuve éxito en combinarlos yo mismo.
TemporalWolf

2
Si !=devuelve False, Python se cortocircuita y no pasa nada; El intérprete sale normalmente. Si devuelve True, >_genera un NameError, porque la variable _no está definida.
Dennis

Las cifras encadenan las comparaciones en mi respuesta y luego pierdo el resultado obvio en su comentario. Gracias por la explicación.
TemporalWolf

3

sfk , 176 bytes

* originalmente era Bash + SFK, pero desde entonces TIO ha agregado un envoltorio SFK adecuado

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

Pruébalo en línea!


¿Verificando primero la impresión de error nc [addr] 1 -w1acortaría esto?

@Rogem ncacepta los ceros a la izquierda, así como las direcciones IPv6, por lo que todavía tendría que manejarlos, y de sfktodos modos esto se pretende más como una respuesta que como una respuesta de shell.
Precioso

3

Python3 Bash * 60

* También otras conchas. Cualquiera para el que la prueba de verdad / falsedad pase un código de salida del programa

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

Explicación

El problema con las soluciones puras de Python es que el bloqueo de un programa se considera indeterminado. Podríamos usar un "lote" de código para convertir una excepción en un valor verdadero / rápido apropiado. Sin embargo, en algún momento el intérprete de Python maneja esta excepción no detectada y devuelve un código de salida distinto de cero. ¡Por el bajo costo de cambiar los idiomas a su shell de Unix favorito, podemos ahorrar bastante código!

Por supuesto, esto es vulnerable a los ataques de inyección ... ¡Entradas como 1.1.1.1'); print('Doing Something Eviluna amenaza no mitigada!


( Explicación es (no explicación ).)
Peter Mortensen

@PeterMortensen Yikes. Incluso estaba subrayado en rojo. Mi navegador intentó salvarme, pero no quise escuchar. Gracias por atrapar eso!
Sompom

Los programas completos pueden salir a través de códigos de salida, por lo tanto, esto podría ser de 43 bytes .
ბიმო

@BMO Interesante. ¡Gracias por señalar eso! Creo que la definición del problema cambió de "Verdad / Falsificación" a permitir también una salida arbitraria desde que publiqué esto, pero podría no haberlo notado antes :)
Sompom

3

ECMAScript regex puro, 41 bytes

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

Pruébalo en línea!
Pruébalo en regex101

Creo que la lógica en esta expresión regular habla por sí misma, por lo que simplemente imprimiré bonito pero no lo comentaré:

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

Esto se puede usar para eliminar 2 bytes de las siguientes otras respuestas:

Aquí hay una versión alternativa que permite los ceros a la izquierda, pero lo hace de manera consistente (los octetos pueden estar representados por un máximo de 3 dígitos decimales):

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

O permita cualquier número de ceros a la izquierda:

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


1
\by \B... es inteligente!
mazzy

1
@mazzy Sí, ¡esos dos son realmente útiles! Podría haber usado en su (?!0\d)lugar, ¡pero me gusta \Bmás!
Código muerto el

La respuesta de PowerShell no se acorta con tu expresión regular. Lo siento. Se necesitan comillas para convertir una matriz en una cadena. Pruébalo en línea!
mazzy

1
También \.?\bme ahorró un byte en mi respuesta, ¡gracias!
Neil

1
Guardado 3 bytes thx
l4m2

2

Rojo , 106 bytes

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]

Pruébalo en línea!

Devolver trueofalse

Explicación:

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 bytes

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

Ejecutar y depurarlo

Desempaquetado, sin golf y comentado, se ve así.

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?

Ejecute este


¡Sorprendido de saber que hiciste el lenguaje Stax! está funcionando bien
RV7

¡Gracias! El espacio de los idiomas de golf está sorprendentemente lleno de gente, y no estoy seguro de si Stax puede justificar su propia existencia según sus méritos, pero mi objetivo principal era ver si podía hacerlo y tal vez aprender algo. Terminó siendo más divertido de lo esperado.
recursivo el

2

Python 3, 109 93 bytes

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

Explicación

Cada octeto puede ser 0-255:

  • comienza con 25 y tiene 0-5 como último dígito
  • comienza con 2, tiene 0-4 como segundo dígito y cualquier dígito al final
  • comienza con 1 y 00-99 como dígitos de descanso
  • tiene solo 2 dígitos: 1-9 es el primero y cualquier dígito posterior
  • o solo un dígito

Un octeto puede terminar con un (.) O simplemente terminar, con la condición de que no pueda hacer las dos cosas, la anticipación negativa (?!$)se ocupa de este caso

Gracias @Zachary por hacerme darme cuenta de que puedo descartar espacios (ya que es un código de golf)
Gracias @DLosc por las mejoras y hacerme dar cuenta de mi error, ya se ha corregido.


2
Alguna explicación para esto podría ayudar.
Nissa

x: re.match=> x:re.match; , x=> ,x, y ) is=> )isdebería guardar 3 bytes. Además, en la expresión regular, puede usar \dpara cada aparición de [0-9], y [1]=> 1. ¡Sin embargo, esta parece ser una excelente primera publicación!
Zacharý

[1-9][0-9]|[0-9]puede convertirse [1-9]\d|\d(según el consejo de Zacharý), que puede convertirse [1-9]?\d. Además, en lugar de probar re.match(...)is not None, puede hacerlo bool(re.match(...))ya que los objetos de coincidencia son verdaderos y Nonefalsey. :)
DLosc

Hmm En realidad, esto falla en el caso de prueba 1.2.3.4.5(y también 1.2.3.4., que no está en la lista oficial de casos de prueba), porque puede coincidir con un punto en lugar del final de la cadena después del cuarto número.
DLosc


2

Carbón , 45 21 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 24 bytes al portar la respuesta de @ Shaggy's Japt. Explicación:

    θ                   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

Falla en casos de prueba con enteros negativos como 123.-50.0.12o 1.1.1.-80. Todo lo demás parece estar funcionando bien. Entonces el <256cheque debería ser in [0,255]en su lugar.
Kevin Cruijssen

@KevinCruijssen En realidad, el código para filtrar caracteres no válidos no funcionaba porque olvidé cambiar la variable en el bucle interno. Debería arreglarse ahora.
Neil

2

Retina , 46 44 bytes

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

Puerto de la respuesta Java de @ OlivierGrégoire , ¡así que asegúrese de votarlo!
-2 bytes gracias a @Neil .

Pruébalo en línea .

Explicación:

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

Mi intento (que no publiqué porque la pregunta quedó en espera en ese momento) fue de la misma longitud, pero no tenía la \doptimización del grupo, por lo que puede guardar dos bytes porque no necesita la Mespecificación en el Última línea.
Neil

Logré reducir Retina a 42 bytes al portar la respuesta de Perl 6, pero esta respuesta también funciona en 0.8.2, lo que no hace mi puerto.
Neil

2

Jalea , 11 bytes

⁹ḶṾ€ṗ4j€”.ċ

10 02564 4=4294967296

dieciséis256

¿Cómo?

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

¿Por qué la versión con 65.536 IP tarda 1.8 segundos? o_O
Dennis

2

Retina , 42 41 bytes

~(K`

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

Pruébalo en línea! Basado en una versión anterior de la respuesta de Perl 6 de @nwellnhof, pero se guardó 1 byte al robar el \.?\btruco de la respuesta de @ Deadcode. Explicación:

K`

Despeje el área de trabajo.

255*

Insertar 255 caracteres.

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

Genere el rango 0..255 separado con |s, con el prefijo ^((y con el sufijo )\.?\b){4}$, construyendo así la expresión regular ^((0|1|...255)\.?\b){4}$.

~(

Evalúe eso en la entrada original.


1

Pip , 25 16 bytes

a~=X,256RL4J"\."

Toma la dirección IP candidata como argumento de línea de comando. Pruébalo en línea! o Verificar todos los casos de prueba

Explicación

Solución Regex, esencialmente un puerto de respuesta Stax recursiva .

                  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 bytes

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

Pruébalo en línea!

Cree RegExpgrupos de captura a partir de índices de una matriz que tiene length 256un rango 0-255unido con |y seguido de un .carácter escapado ( ^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$) repetidas 3veces cerrando con una matriz unida seguido de $para coincidir con el final de la cadena, el retorno trueo el falseresultado de la entrada pasada RegExp.prototype.test().

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.