Mascarar um endereço IP e transmitir

12

fundo

Inspirado por essa pergunta do Unix.SE (e, claro, minha própria resposta ).

Quando um endereço IP é especificado para uma interface, geralmente é fornecido na forma decimal com pontos:

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

onde a.b.c.dé o endereço real e e.f.g.hé a máscara de rede.

A máscara de rede, quando representada em binário, é basicamente um monte de 1bits seguido por um monte de 0bits. Quando a máscara de rede é AND bit a bit no endereço IP fornecido, o resultado será a parte da rede do endereço ou simplesmente o endereço de rede . Isso será programado na tabela de rotas do host para que o host saiba enviar qualquer coisa destinada a esta rede por essa interface.

O endereço de broadcast de uma rede é obtido pegando o endereço de rede (de cima) e configurando todos os bits do host como 1. O endereço de broadcast é usado para enviar a todos os endereços dentro da rede especificada.

Desafio

Dado um endereço IP decimal com pontos e uma máscara de rede válida como entrada, forneça o endereço de rede e o endereço de broadcast como saída, também no formato decimal com pontos.

  • A entrada deve ser endereço e máscara como duas cadeias de caracteres no formato decimal com pontos. Você pode passar isso como 2 cadeias separadas, como lista ou matriz de 2 elementos de cadeia ou uma única cadeia com o endereço e a máscara separados por algum separador sensível.
  • O formato de saída está sujeito às mesmas restrições que o formato de entrada.

Exemplos

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
fonte
2
A máscara de rede terá apenas 255s e 0s?
Xnor
1
@xnor O último exemplo está 252nele.
user81655
2
A última saída não deveria ser 10.24.0.0 10.27.255.255?
PurkkaKoodari
2
@ Pietu1998 não, 255.252.0.0 é uma máscara válida. Em binário, é 11111111.11111100.00000000.00000000
Digital Trauma
2
@ Pietu1998 Oh sim - desculpe - está consertado agora.
Digital Trauma

Respostas:

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`.`

Explicação

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

Teste

user81655
fonte
4

MATL , 47 bytes

Esta resposta usa a versão atual (4.0.0) do idioma.

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

Exemplo

>> 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

Explicação

'%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
fonte
0

PHP, 126 bytes

Com entrada em $ 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";

E uma versão mais legível:

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_filterrequer uma única declaração no padrão de substituição ao usar o esinalizador, portanto, 'anexo' o resultado dos cálculos aos valores 5 e superior de $ a, porque esses nunca são reutilizados.

Aurel Bílý
fonte
0

Perl, 90 85 bytes

inclui +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

Mais legível:

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

O -F/\D/divide a entrada na não-dígitos e armazena em @F.

Kenney
fonte
0

Fator, 103 bytes

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

Agradável.

Ungolfed:

: 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
fonte
0

PHP , 74 bytes

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

Como autônoma, a entrada é via linha de comando:

$ php ip.php 192.168.0.1 255.255.255.0
192.168.0.0 192.168.0.255

Experimente online!

Ou como uma função, 80 bytes :

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

Experimente online!

Ungolfed

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 ) ];
}

O PHP possui ótimos (embora com nomes de funções longos) embutidos para manipular a cadeia de caracteres pontilhada IPv4 para binária e vice-versa.

Resultado

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
640KB
fonte