Enmascarar una dirección IP y transmitirla

12

Antecedentes

Inspirado por esta pregunta de Unix.SE (y, por supuesto, mi propia respuesta ).

Cuando se especifica una dirección IP para una interfaz, a menudo se proporciona en esta forma decimal con puntos:

a.b.c.d e.f.g.h

donde a.b.c.destá la dirección real y e.f.g.hes la máscara de red.

La máscara de red, cuando se representa en binario, es básicamente un montón de 1bits seguidos de un montón de 0bits. Cuando la máscara de red se ANDA bit a bit contra la dirección IP dada, el resultado será la porción de red de la dirección, o simplemente la dirección de red . Esto se programará en la tabla de rutas del host para que el host sepa enviar todo lo destinado a esta red a través de esta interfaz.

La dirección de transmisión para una red se obtiene tomando la dirección de red (desde arriba) y configurando todos los bits de host en 1. La dirección de transmisión se usa para enviar a todas las direcciones dentro de la red dada.

Desafío

Dada una dirección IP decimal con puntos y una máscara de red válida como entrada, proporcione la dirección de red y la dirección de difusión como salida, también en formato decimal con puntos.

  • La entrada debe ser dirección y máscara como dos cadenas en formato decimal con puntos. Puede pasar esto como 2 cadenas separadas, como una lista o matriz de 2 elementos de cadena o una sola cadena con la dirección y la máscara separadas por algún separador sensible.
  • El formato de salida está sujeto a las mismas restricciones que el formato de entrada.

Ejemplos

Input                              Output

192.168.0.1 255.255.255.0          192.168.0.0 192.168.0.255
192.168.0.0 255.255.255.0          192.168.0.0 192.168.0.255
192.168.0.255 255.255.255.0        192.168.0.0 192.168.0.255
100.200.100.200 255.255.255.255    100.200.100.200 100.200.100.200
1.2.3.4 0.0.0.0                    0.0.0.0 255.255.255.255
10.25.30.40 255.252.0.0            10.24.0.0 10.27.255.255
Trauma digital
fuente
2
¿La máscara de red solo tendrá 255 y 0?
xnor
1
@xnor El último ejemplo tiene 252en él.
user81655
2
¿No debería ser la última salida 10.24.0.0 10.27.255.255?
PurkkaKoodari
2
@ Pietu1998 no, 255.252.0.0 es una máscara válida. En binario es 11111111.11111100.00000000.00000000
Digital Trauma
2
@ Pietu1998 Oh sí, lo siento, ya está arreglado.
Trauma digital

Respuestas:

5

JavaScript (ES6), 92 bytes

(a,m)=>a.split`.`.map((n,i)=>(v=m[i],m[i]=n&v|v^255,n&v),m=m.split`.`).join`.`+" "+m.join`.`

Explicación

(a,m)=>
  a.split`.`
  .map((n,i)=>(
      v=m[i],
      m[i]=n&v|v^255,
      n&v
    ),
    m=m.split`.`
  ).join`.`
  +" "+m.join`.`

Prueba

usuario81655
fuente
4

MATL , 47 bytes

Esta respuesta usa la versión actual (4.0.0) del idioma.

'%i.%i.%i.%i't32whh2:"j'\d+'XXU]tbZ&tb255Z~+hYD

Ejemplo

>> matl
 > '%i.%i.%i.%i't32whh2:"j'\d+'XXU]tbZ&tb255Z~+hYD
 > 
> 192.168.0.1
> 255.255.255.0
192.168.0.0 192.168.0.255

Explicación

'%i.%i.%i.%i't32whh      % format string: '%i.%i.%i.%i %i.%i.%i.%i'
2:"                      % for loop: do this twice
    j'\d+'XXU            % input string and parse into 4-vector with the numbers
]                        % end
tbZ&                     % compute network address
tb255Z~+                 % compute broadcast address
hYD                      % concatenate into 8-vector and apply format string
Luis Mendo
fuente
0

PHP, 126 bytes

Con entrada en $ n:

preg_filter(~Ð×£ÔÖÐ,~Û¤¢Â×ÛÎÖÑ×ÛÔÔÁÌÀ×ÛÑÂ×ÛÂÛÁÊÀÝÑÝÅÝÝÖÑ×Û¤ÛÒÊ¢ÙÛÎÖÖÑ×ÛÑÂÛÑ×Û¤ÛÒÊ¢ÍÊÊÙÛÎÖÖÅÝÝÖ,$n);echo"$c $b";

Hexdump:

0000000: 7072 6567 5f66 696c 7465 7228 7ed0 d7a3  preg_filter(~...
0000010: 9bd4 d6d0 9a2c 7edb 9ea4 a2c2 d7db ced6  .....,~.........
0000020: d1d7 db96 d4d4 c1cc c0d7 db9c d1c2 d7db  ................
0000030: 8bc2 db96 c1ca c0dd d1dd c5dd ddd6 d1d7  ................
0000040: db9e a4db 96d2 caa2 d9db ced6 d6d1 d7db  ................
0000050: 9dd1 c2db 8bd1 d7db 9ea4 db96 d2ca a283  ................
0000060: cdca cad9 81db ced6 d6c5 dddd d62c 246e  .............,$n
0000070: 293b 6563 686f 2224 6320 2462 223b       );echo"$c $b";

Y una versión más legible:

preg_filter( /* PCRE regex on input */
    '/(\d+)/e', /* match all digits, execute the code for each one */
    '$a[]=($1) /* push the matched value to the array $a */
        .($i++>3 /* if we're at the 5th or higher digit */
            ?($c.=($t=$i>5?".":"").($a[$i-5]&$1)) /* append to $c bitwise AND-ed number */
                .($b.=$t.($a[$i-5]|255&~$1)) /* append to $b the broadcast address */
            :"")',
    $n);
echo"$c $b"; /* output $c and $b */

preg_filterrequiere una sola declaración en el patrón de reemplazo cuando se usa la ebandera, por lo que 'agrego' el resultado de los cálculos a los valores 5 y superiores de $ a, porque nunca se reutilizan.

Aurel Bílý
fuente
0

Perl, 90 85 bytes

incluye +6 para -pF/\D/

for(0..3){push@a,$F[$_]&1*($y=$F[$_+4]);push@b,$F[$_]|~$y&255}$"='.';$_="@a @b"

Uso:

echo "192.168.0.1 255.255.255.0" | perl -pF/\\D/ file.pl

Más legible:

for(0..3) {
    push @a, $F[$_] & 1*($y=$F[$_+4]);  # calc/add network address 'byte'
    push @b, $F[$_] | ~$y & 255         # calc/add broadcast address 'byte'
}
$"='.';                                 # set $LIST_SEPARATOR
$_="@a @b"                              # set output to network address and broadcast

El -F/\D/divide la entrada a los no dígitos y lo almacena en @F.

Kenney
fuente
0

Factor, 103 bytes

[ [ ipv4-aton ] bi@ 2dup bitand -rot dup bit-count 32 - abs on-bits pick bitor 2nip [ ipv4-ntoa ] bi@ ]

Agradable.

Sin golf:

: mask-and-broadcast ( ip mask -- netaddr broadcast )
  [ ipv4-aton ] bi@ 2dup bitand -rot dup bit-count 32 - abs on-bits pick bitor 2nip
  [ ipv4-ntoa ] bi@ ;
gato
fuente
0

PHP , 74 bytes

<?=long2ip($i=ip2long($argv[1])&$m=ip2long($argv[2])),' ',long2ip($i|~$m);

Como independiente, la entrada es a través de la línea de comando:

$ php ip.php 192.168.0.1 255.255.255.0
192.168.0.0 192.168.0.255

Pruébalo en línea!

O como una función, 80 bytes :

function($a,$b){return[long2ip($i=ip2long($a)&$m=ip2long($b)),long2ip($i|~$m)];}

Pruébalo en línea!

Sin golf

function ip( $a, $b ) {
    $i = ip2long( $a );          // string IP to 32 bit int
    $m = ip2long( $b );          // string netmask to 32 bit int
    $n = $i & $m;                // network is bitwise AND of IP and netmask
    $c = $i | ~$m;               // broadcast is bitwise OR of IP and inverse netmask
    return [ long2ip( $n ), long2ip( $c ) ];
}

PHP tiene buenas incorporaciones (aunque con nombres de funciones largos) para manejar la cadena de puntos IPv4 a binario y viceversa.

Salida

192.168.0.1 255.255.255.0   => 192.168.0.0 192.168.0.255
192.168.0.0 255.255.255.0   => 192.168.0.0 192.168.0.255
192.168.0.255 255.255.255.0 => 192.168.0.0 192.168.0.255
100.200.100.200 255.255.255.255 => 100.200.100.200 100.200.100.200
1.2.3.4 0.0.0.0 => 0.0.0.0 255.255.255.255
10.25.30.40 255.252.0.0 => 10.24.0.0 10.27.255.255
640 KB
fuente