Desafío
Dado un IPv4 address
en notación de cuatro puntos y un IPv4 subnet
en notación CIDR , determine si address
está en el subnet
. Genere un valor distinto y coherente si está en el subnet
, y un valor distinto distinto y coherente si no está en el subnet
. Los valores de salida no necesariamente tienen que ser veraz / falsey en su idioma.
Breve introducción a la notación de subred CIDR
Las direcciones de red IPv4 tienen 32 bits de longitud, divididas en cuatro grupos de 8 bits para facilitar la lectura. La notación de subred CIDR es una máscara del número especificado de bits, que comienza en el extremo izquierdo. Por ejemplo, para una /24
subred, esto significa que los 8 bits más a la derecha de la dirección están disponibles en esa subred. Por lo tanto, dos direcciones que están separadas como máximo 255
y tienen la misma máscara de subred, están en la misma subred. Tenga en cuenta que los CIDR válidos tienen todos los bits de host (el lado derecho) sin establecer (ceros).
xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^--- subnet mask ---^ ^-hosts-^
Para otro ejemplo, una /32
subred especifica que todos los bits son la máscara de subred, lo que significa que solo se permite un host por /32
.
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^--- subnet mask ---^
Ejemplos:
Usando True
para "en la subred" y False
para "no en la subred" como salida:
127.0.0.1
127.0.0.0/24
True
127.0.0.55
127.0.0.0/23
True
127.0.1.55
127.0.0.0/23
True
10.4.1.33
10.4.0.0/16
True
255.255.255.255
0.0.0.0/0
True
127.1.2.3
127.0.0.0/24
False
127.1.2.3
127.1.2.1/32
False
10.10.83.255
10.10.84.0/22
False
Reglas y aclaraciones
- Dado que el análisis de entrada no es el punto interesante de este desafío, se garantiza que obtendrá direcciones IPv4 y máscaras de subred válidas.
- La entrada y salida se pueden dar por cualquier método conveniente .
- Puede imprimir el resultado en STDOUT o devolverlo como resultado de una función. Indique en su envío qué valores puede tomar la salida.
- Un programa completo o una función son aceptables.
- Las lagunas estándar están prohibidas.
- Este es el código de golf, por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
fuente
10.0.0.1/10.0.0.0”/16
?1.255.1.1/8
es una expresión CIDR válida , que representa el host1.255.1.1
dentro de la red1.0.0.0
con una máscara de subred de255.0.0.0
. Sin embargo, el desafío solicita el número de red y la subred específicamente en notación CIDR, que1.255.1.1/8
no es una combinación válida de número de red y subred.Respuestas:
Python 3 (62 bytes)
Muy sencillo:
fuente
ip_adress
objeto y unip_network
objetoany convenient method
, posiblemente permitiendo que Python gane, a menos que un lenguaje de golf basado en Python tenga estos como sus tipos.(host^net)>>(32-mask)
solo tiene 10 bytes. Pero está a medio camino entre las tareas que no incluyen listas de listas o el mapeo de una función en una lista, porque muchas operaciones escalares se pueden hacer con una instrucción de 2 o 3 bytes, y se pueden construir bucles alrededor de cosas en unos pocos bytes.C # (compilador de Visual C #) , 250 + 31 = 281 bytes
Bytecount incluye
using System;using System.Linq;
Pruébalo en línea!
Escribí esto en JS tan pronto como se publicó el desafío, pero Arnauld me ganó con una respuesta mucho mejor, por lo que aquí está en C #.
Definitivamente mucho espacio para jugar al golf.
Explicación:
La función consiste en una subfunción llamada
h
:Esta subfunción divide la dirección IP
.
, convierte cada número en una cadena binaria, deja cada cadena con0
una longitud de 8 bits y luego concatena las cadenas en una cadena binaria de 32 bits.Esto se hace inmediatamente en el lugar con
a=h(a);
la dirección IP dada.Luego dividimos la máscara de subred en una dirección IP y un número de máscara con
c=b.Split('/');
El componente de dirección IP también se pasa a través de nuestra subfunción:
b=h(c[0]);
y el número de máscara se analiza a un entero:var d=int.Parse(c[1]);
Finalmente tomamos los primeros
d
bits de ambas cadenas binarias (donded
está el número de máscara) y las comparamos:return a.Substring(0,d)==b.Substring(0,d);
fuente
rPad
está integrado en cadenas. enlace de pastebin a enlace TIO que es demasiado largo soloShell POSIX de Linux (con net-tools / iputils) (34 bytes sin terminación, 47 bytes con terminación)
¿Qué es más adecuado para analizar máscaras y direcciones de red que las propias utilidades de red? :)
Advertencia: el script es potencialmente perjudicial para su conectividad a Internet, ejecute con cuidado.
Entrada: el script toma la dirección IP probada como primer argumento y la subred probada. como segundo argumento
Salida: el script devuelve un valor verdadero (0) si el primer argumento del script pertenece a la subred indicada en el segundo argumento. De lo contrario, nunca terminará.
Suposiciones: el script debe ejecutarse como usuario root, en un entorno limpio ( es decir , el administrador no ha establecido ninguna otra ruta de agujero negro, y si se ha ejecutado una instancia anterior del script, la ruta de agujero negro que creó se ha eliminado ) El script también asume una "conexión a Internet que funciona" ( es decir , una ruta predeterminada válida está presente).
Explicación:
Creamos una ruta de agujero negro a la subred especificada. Luego probamos la conectividad a la dirección IP proporcionada mediante ping . Si la dirección no pertenece a la subred (y dado que suponemos una conexión a Internet configurada correctamente), ping intentará enviar paquetes a esa dirección. Tenga en cuenta que si esta dirección realmente responde no importa, ya que ping seguirá intentándolo para siempre. Por el contrario, si la dirección pertenece a la subred, el ping fallará con ENETUNREACH y devolverá 2, y dado que negamos el comando, el script tendrá éxito.
Ejemplo
Pruebe si 5.5.5.5 pertenece a 8.8.8.0/24
(Limpiar con
sudo ip route del 8.8.8.0/24
después de ejecutar el comando).Pruebe si 5.5.5.5 pertenece a 5.5.5.0/24:
(Limpiar con
sudo ip route del 5.5.5.0/24
después de ejecutar el comando).Pruebe si 8.8.8.8 pertenece a 5.5.5.0/24:
(Limpiar con
sudo ip route del 5.5.5.0/24
después de ejecutar el comando).Versión de 47 bytes si no permitimos scripts que no terminen
Según el comentario de @ Grimy, aquí está la versión que siempre termina y devuelve 0 (verdadero) si la dirección está en la subred y 1 (falso) en caso contrario. Hacemos que el ping termine con el
-c1
indicador que limita el número de paquetes enviados a 1. Si la dirección respondió, el ping devolverá 0, y si no, el ping devolverá 1. Solo si la dirección pertenece a la subred de blackholed, el ping devolverá 2, que es lo que probamos en el último comando.fuente
ping
que moriría de SIGPIPE si se ejecutara con stdout + stderr conectado a otro programa, y el lector cerró la tubería. Y ese es el caso de uso más probable porque el estado de salida puede ser exitoso de cualquier manera (si agregamos una-c1
opción para hacer ping para establecer el conteo). Pero claro, la lectura de su salidavar=$(/a.sh)
fallará; necesitaría un lector que se detuviera después de decidir, en lugar de leer todo el resultado y luego mirarlo.ping
que terminará en menos de, digamos, un segundo en caso de una dirección de blackholed). ¡Agregué una versión final por 13 bytes adicionales! :)JavaScript (ES6), 82 bytes
Toma entrada como
(address)(subnet)
. Devuelve un valor booleano.Pruébalo en línea!
fuente
PHP ,
1019288 bytes-13 bytes de @gwaugh
Pruébalo en línea!
fuente
function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
strtok()
. La suya es 4 bytes más corta que mi respuesta muy similar a continuación. ¡Accesorios!PowerPC / PPC64 C,
116114 bytes(Probado en x86_64 Ubuntu 18.04 usando powerpc64-linux-gnu-gcc -static y qemu-user).
El programa toma las dos líneas en la entrada estándar y, como código de salida, devuelve 1 si la dirección coincide y 0 si no. (Por lo tanto, esto depende de que la especificación no requiera un valor verdadero para una coincidencia y un valor falsey para una falta de coincidencia). Tenga en cuenta que si está ejecutando de forma interactiva, deberá indicar EOF (
^D
) tres veces después de ingresar a la segunda línea.Esto depende de que PowerPC sea big-endian, y también de que la plataforma devuelva 0 para desplazar a la derecha un valor sin signo de 32 bits por 32. Lee los octetos en valores sin signo uno por uno, junto con la longitud de la máscara de red en otro byte ; luego toma el xor de las dos direcciones de 32 bits sin signo y desplaza los bits irrelevantes. Finalmente se aplica
!
para satisfacer el requisito de devolver solo dos valores distintos.Nota: Se podría ser posible afeitar de dos bytes, reemplazando
u+3
conp
y que requieren compilación con-O0
. Sin embargo, eso es vivir más peligrosamente de lo que me importa.Gracias a Peter Cordes por la inspiración para esta solución.
Más portátil C,
186171167 bytesAquí preservaré una versión más portátil que ejecuta 167 bytes.
Este programa toma las dos líneas en la entrada estándar y devuelve el código de salida 1 si la dirección está en la subred y 0 si no lo está. (Por lo tanto, esto depende de que la especificación no requiera un valor verdadero para las coincidencias y un valor falso para las no coincidencias).
Un desglose de la expresión central:
a^e
,b^f
,c^g
,d^h
Calcula el XOR de la dirección y la máscara de byte a byte.(((a^e)<<8|b^f)<<8|c^g)<<8|d^h
luego los combina en un solo valor de 32 bits sin signo mediante un método similar a Horner....>>32-n
luego cambia los bits de la diferencia xor que no son relevantes para la máscara de subred (teniendo en cuenta que-
tiene mayor prioridad en C que<<
)~0U<<32
, dará un comportamiento indefinido asumiendo queunsigned
es de 32 bits (que está en prácticamente todas las plataformas actuales). Por otro lado, si n = 0, cualquier dirección coincidirá, porn&&...
lo que dará el resultado correcto (aprovechando el comportamiento de cortocircuito de&&
).!
a la salida 0 o 1.-15 bytes debido a los comentarios de ceilingcat y AdmBorkBork
-4 bytes debido al comentario de Peter Cordes
fuente
unsigned
. por ejemplo, conchar*p=&a
thenp++,p++,p++,...
op--,...
como scanf args. Sin"%hhu.%hhu..."
embargo, la cadena de formato debería ser , por lo que es una compensación significativa entre ese tamaño adicional frente a declarar menos variables y poder hacerlo(a^b)>>(32-count)
Stax , 22 bytes
Ejecutar y depurarlo
Toma los parámetros de entrada separados por espacios en la entrada estándar.
Desempaquetado, sin golf y comentado, se ve así.
Ejecute este
fuente
Función de código de máquina x86-64,
5348 bytesregistro de cambios:
jz
sobre el turno en lugar de usar un turno de 64 bits para manejar el>>(32-0)
caso especial.setnz al
.(Véase también la respuesta del código de máquina de 32 bits de Daniel Schepler basada en esto, que luego evolucionó para usar algunas otras ideas que teníamos. Incluyo mi última versión de eso al final de esta respuesta).
Devuelve ZF = 0 para el host no en la subred, ZF = 1 para la subred, por lo que puede ramificar el resultado con
je host_matches_subnet
Se puede llamar con la convención de llamadas del sistema V x86-64 como
bool not_in_subnet(int dummy_rdi, const char *input_rsi);
si agregarasetnz al
.La cadena de entrada contiene el host y la red, separados por exactamente 1 carácter sin dígitos. La memoria que sigue al final del ancho del CIDR debe contener al menos 3 bytes sin dígitos antes del final de una página. (No debería ser un problema en la mayoría de los casos, como para un cmdline arg.) La versión de 32 bits de Daniel no tiene esta limitación.
Ejecutamos el mismo bucle de análisis de cuatro puntos con puntos 3 veces, obteniendo las dos direcciones IPv4 y obteniendo el
/mask
como un entero en el byte alto de una palabra d. (Esta es la razón por la que debe haber memoria legible después del/mask
, pero no importa si hay dígitos ASCII).Lo hacemos
(host ^ subnet) >> (32-mask)
para cambiar los bits del host (los que no pueden coincidir), dejando solo la diferencia entre la subred y el host. Para resolver el/0
caso especial en el que necesitamos cambiar por 32, saltamos sobre el cambio en cuenta = 0. (neg cl
establece ZF, que podemos ramificar y dejar como valor de retorno si no cambiamos). Tenga en cuenta que32-mask mod 32 = -mask
, y los cambios escalares x86 enmascaran su recuento en& 31
o& 63
.(no actualizado con la última versión) Pruébelo en línea!
incluido un
_start
que lo activaargv[1]
y devuelve un estado de salida.Funciona bien si pasa una línea de comando arg que contiene una nueva línea en lugar de un espacio. Pero tiene que ser en su lugar , no tan bien.
Función de código de máquina x86 de 32 bits, 38 bytes
Hacer 9 enteros -> uint8_t analiza y "empujarlos" en la pila, donde los sacamos como dwords o usamos el último todavía en CL. Evita leer más allá del final de la cadena en absoluto.
Además,
dec
solo tiene 1 byte en modo de 32 bits.Llamada de prueba
fuente
cmp/jcc
que mencionaste, hicieras algo asíxor edx,edx;neg cl;cmovz eax,edx;shr eax,cl
, o tal vez ya tengas un valor 0 en alguna parte. (Y entonces no necesitarías lassub cl,32
instrucciones.)edi
debería ser 0 cuando sale el bucle, por lo quexor eax,edx;neg cl;cmovz eax,edi;shr eax,cl
debería funcionar.cmove eax,edi
tiene 3 bytes, que es un lavado sobre el eliminado,sub cl,32
luegoshr cl,eax
guarda un byteshr cl,rax
y 32 bitsdec edi
guarda un byte sobre 64 bitsdec edi
. Mi ensamblaje luego da.byte 0x33
(en la sintaxis binutils de GNU) = 51 parain_subnet.size
.shr eax,cl
,shr %cl, %eax
en comparación con la sintaxis de AT&T, su último comentario revirtió eso). Es un poco complicado actualizar las respuestas del código de máquina (y portar a la_start
persona que llama y volver a describir la convención de llamada para el modo de 32 bits ... .), así que podría no llegar a eso. Sentirse flojo hoy. >. <edi
escritura, escribir la salida, etc., terminó ahorrando 2 bytes en la red. (Al menos una vez me di cuenta de quepush ecx;push ecx;push ecx
era más corto quesub esp,12
; y parecía ser un lavado si predecrementabaedi
y usabastd;stosb;cld
o si simplemente almacenaba usandodec edi;mov [edi],al
.Jalea , 23 bytes
Pruébalo en línea!
Enlace monádico que toma una dirección y una subred separadas por una barra diagonal y devuelve 1 para verdadero y 0 para falso.
Gracias a @gwaugh por señalar una falla en el original: no se pudo garantizar que la lista binaria fuera de 32 años.
fuente
Perl 5
-Mbigint -MSocket=:all -p
, 72 bytesPruébalo en línea!
fuente
05AB1E , 21 bytes
Toma la subred antes de la dirección.
Pruébelo en línea o verifique todos los casos de prueba .
Explicación:
fuente
R 120 bytes
una función - pegué ".32" al primer término
w=function(a,b){f=function(x)as.double(el(strsplit(x,"[./]")));t=f(paste0(a,".32"))-f(b);sum(t[-5]*c(256^(3:0)))<2^t[5]}
y solo por diversión:
require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]
que es 56 bytes
fuente
PHP ,
757371 bytesUna bifurcación de la respuesta de @Luis felipe De jesus Muñoz , como una entrada independiente tomando argumentos de la línea de comando. Salidas
'1'
para Truthy,''
(cadena vacía) para Fasley.Pruébalo en línea!
-2 bytes tomando prestado el pequeño truco de @Christoph
strtok()
. Sin embargo, su respuesta es aún más corta.fuente
función de montaje x86,
4943 bytesEsto se publica principalmente para satisfacer la solicitud de Peter Cordes de la versión revisada que creé. Probablemente puede desaparecer una vez / si lo incorpora en su respuesta.
Esta función espera
esi
apuntar a una cadena de entrada, con la dirección y las partes de subred separadas por un espacio o un carácter de nueva línea, y el valor de retorno está en el indicador ZF (que por definición solo tiene dos valores posibles).Y la parte del contenedor x86 de Linux:
-6 bytes debido a la sugerencia de Peter Cordes para devolver el valor en ZF.
fuente
xor edx,edx
y reemplazarcmovz eax,edx
conjz .nonzero; xor eax,eax; .nonzero:
.cmovz
todavía gana si tenemos convenio de convocatoriaebx=0
.jz
pasarshr
al setz o al ret? Podemos cambiar elsetnz
asetz
y volver1
para un partido si eso ayuda. O incluso decir que nuestro valor de retorno es ZF. Debería haber hecho eso en mi respuesta. (Pero no creo que podamos justificar que se requiera que la persona que llama cree constantes para nosotros, por ejemploebx=0
. Mi respuesta en Consejos para jugar golf en código de máquina x86 / x64 argumenta que extendería demasiado una convención de llamada personalizada.cut
para eliminar algunas columnas de la salida del listado NASM porque todas mis instrucciones son cortos:nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Además, utilicé mov en lugar de movzx en mi_start
llamador porque el estado de salida proviene del byte bajo de arg asys_exit()
. El núcleo ignora los bytes más altos.setnz al
despuéscall in_subnet
en el contenedor.call
/je
, en lugar de imprimir o transmitir el resultado. Como señalé en los "consejos", algunas convenciones de llamadas de llamadas al sistema ya hacen esto en la vida real (generalmente con CF = error).Java
215 211 207 202 200 199 198 190180 bytesSalidas
true
para la verdad yfalse
para la falsedad.Nota: Esto se usa en
long
lugar deint
para el posible desplazamiento a la derecha de 32.Pruébalo en línea!
Guardado 1 byte gracias a ceilingcat
Guardado 10 bytes gracias a Peter Cordes
fuente
host ^ net
para desplazar los bits que desea eliminar, en lugar de crear una máscara. Pero supongo que Java necesita una comparación allí para crear un booleano a partir de un entero. Tal vez a!
, porque no importa cuál de verdadero o falso produzca para qué salida. (Le pedí al OP que me aclarara si tenían la intención de excluir 0 / no cero, y me dijeron que sí, que estaban al tanto de las consecuencias de esa redacción:long
hacer me pierde algunos bytes, pero lo compensé al poder eliminar el ternario y hacer el XOR como usted sugiere. Estoy comprobando qué más puedo jugar al golf antes de publicarCarbón , 36 bytes
Pruébalo en línea! El enlace es a la versión detallada del código. Toma la subred como primer parámetro y emite
-
solo si la dirección se encuentra dentro de la subred. Explicación:Divide la subred
/
.Quítate la máscara y échala al número entero.
Empuje la dirección a la matriz.
Divida ambas direcciones
.
, conviértalas en enteros, interprete como base 256 y descarte los bits enmascarados.Compara los dos valores.
fuente
Japt , 26 bytes
Intentalo
-3 bytes gracias a @Shaggy!
La entrada es una matriz con 2 elementos
[address, subnet]
. Transpilado JS a continuación:fuente
++
.g
método me está molestando; no puedo encontrar una forma de evitarlo en absoluto. Al menos no uno que te ahorre un byte.C # (compilador interactivo de Visual C #) , 187 bytes
Definitivamente puedo jugar más golf.
Pruébalo en línea!
fuente
C # (compilador interactivo de Visual C #) , 134 bytes
Pruébalo en línea!
Sentencia LINQ que toma una matriz de cadena de 2 elementos como entrada en
[address, subnet]
formato.Cada quad punteado se convierte en 32 bits de largo utilizando la manipulación de bits. Los bits se desplazan a la derecha por el tamaño de la subred y los elementos se comparan para la igualdad.
Hubo un par de respuestas de C # en el momento en que se publicó esta respuesta, pero ninguna que utilizara una manipulación de bits pura.
fuente
Rubí (48 bytes)
fuente
====